Skip to content

Commit

Permalink
Update to ver.5.0.0
Browse files Browse the repository at this point in the history
Added Test-ValentiaCredential, Remove-ValentiaCredential
Revised Ping-ValentiaAsync
  • Loading branch information
guitarrapc committed Jan 19, 2016
1 parent 85165b5 commit 506752d
Show file tree
Hide file tree
Showing 10 changed files with 378 additions and 135 deletions.
7 changes: 5 additions & 2 deletions valentia/CS/CredRead.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public Credential GetCredential()
throw new InvalidOperationException("Invalid CriticalHandle!");
}
}

override protected bool ReleaseHandle()
{
if (!IsInvalid)
Expand All @@ -107,4 +107,7 @@ override protected bool ReleaseHandle()
public static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag, out IntPtr CredentialPtr);

[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
public static extern bool CredFree([In] IntPtr cred);
public static extern bool CredFree([In] IntPtr cred);

[DllImport("Advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CredDelete(string target, CRED_TYPE type, int reservedFlag);
169 changes: 169 additions & 0 deletions valentia/CS/PingAsync.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
using System;
using System.Net;
using System.Threading.Tasks;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;

namespace PingEx
{
public class DnsResponse
{
public string HostName { get; private set; }
public IPAddress IPAddress { get; private set; }
public bool IsResolved
{
get
{
IPAddress item = null;
return !IPAddress.TryParse(this.HostName, out item);
}
}

public DnsResponse(string hostName, IPAddress ip)
{
this.HostName = hostName;
this.IPAddress = ip;
}
}

public class DnsResolver
{
public static DnsResponse ResolveIP(IPAddress ip, TimeSpan timeout)
{
Func<IPAddress, IPHostEntry> callback = s => Dns.GetHostEntry(s);
var result = callback.BeginInvoke(ip, null, null);
if (!result.AsyncWaitHandle.WaitOne(timeout, false))
{
return new DnsResponse(ip.ToString(), ip);
}
var hostEntry = callback.EndInvoke(result);
return new DnsResponse(hostEntry.HostName, ip);
}

public static DnsResponse ResolveHostName(string hostNameOrAddress, TimeSpan timeout)
{
Func<string, IPHostEntry> callback = s => Dns.GetHostEntry(s);
var result = callback.BeginInvoke(hostNameOrAddress, null, null);
if (!result.AsyncWaitHandle.WaitOne(timeout, false))
{
return new DnsResponse(hostNameOrAddress, null);
}
var hostEntry = callback.EndInvoke(result);
var ip = hostEntry.AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork);
return new DnsResponse(hostNameOrAddress, ip);
}
}

public class PingResponse
{
public string HostNameOrAddress { get; set; }
public IPAddress IPAddress { get; set; }
public IPStatus Status { get; set; }
public bool IsSuccess { get; set; }
public long RoundTripTime { get; set; }
public bool IsResolved { get; set; }
}

public class NetworkInformationExtensions
{
private static readonly byte[] _buffer = new byte[16];
private static readonly PingOptions _options = new PingOptions(64, false);
private static readonly TimeSpan _pingTimeout = TimeSpan.FromMilliseconds(10);
private static readonly TimeSpan _dnsTimeout = TimeSpan.FromMilliseconds(20);
private static bool _resolveDns = true;

public static async Task<PingResponse[]> PingAsync(string[] hostNameOrAddress)
{
return await PingAsync(hostNameOrAddress, _pingTimeout, _resolveDns, _dnsTimeout);
}

public static async Task<PingResponse[]> PingAsync(string[] hostNameOrAddress, TimeSpan pingTimeout)
{
return await PingAsync(hostNameOrAddress, pingTimeout, _resolveDns, _dnsTimeout);
}

public static async Task<PingResponse[]> PingAsync(string[] hostNameOrAddress, bool resolveDns)
{
return await PingAsync(hostNameOrAddress, _pingTimeout, resolveDns, _dnsTimeout);
}

public static async Task<PingResponse[]> PingAsync(string[] hostNameOrAddress, TimeSpan pingTimeout, bool resolveDns)
{
return await PingAsync(hostNameOrAddress, pingTimeout, resolveDns, _dnsTimeout);
}

public static async Task<PingResponse[]> PingAsync(string[] hostNameOrAddress, TimeSpan pingTimeout, TimeSpan dnsTimeout)
{
return await PingAsync(hostNameOrAddress, pingTimeout, _resolveDns, _dnsTimeout);
}

private static async Task<PingResponse[]> PingAsync(string[] hostNameOrAddress, TimeSpan pingTimeout, bool resolveDns, TimeSpan dnsTimeout)
{
var pingResult = await Task.WhenAll(hostNameOrAddress.Select(async x =>
{
// Resolve only when incoming is HostName.
IPAddress ip = null;
DnsResponse resolve = null;
var isIpAddress = IPAddress.TryParse(x, out ip);
if (!isIpAddress)
{
resolve = DnsResolver.ResolveHostName(x, dnsTimeout);
ip = resolve.IPAddress;
}

// Execute PingAsync
PingReply reply = null;
using (var ping = new Ping())
{
try
{
reply = await ping.SendPingAsync(ip, (int)pingTimeout.TotalMilliseconds, _buffer, _options);
}
catch
{
// ping throw should never stop operation. just return null.
}
}

// set RoundtripTime
long roundTripTime = 0;
if (reply != null) roundTripTime = reply.RoundtripTime;

// set Status
var status = IPStatus.DestinationHostUnreachable;
if (reply != null) status = reply.Status;

// set IsSuccess
var isSuccess = status == IPStatus.Success;

// return when PingFailed || HostName || OmitResolveDns
if (!isSuccess || !isIpAddress || !resolveDns)
return new PingResponse
{
HostNameOrAddress = x,
IPAddress = ip,
Status = status,
RoundTripTime = roundTripTime,
IsSuccess = isSuccess,
IsResolved = !isIpAddress && ip != null,
};

// Resolve Dns only for success host entry.
var host = x;
resolve = DnsResolver.ResolveIP(ip, dnsTimeout);
if (resolve != null) host = resolve.HostName;
return new PingResponse
{
HostNameOrAddress = host,
IPAddress = ip,
Status = status,
RoundTripTime = roundTripTime,
IsSuccess = true,
IsResolved = resolve != null && resolve.IsResolved,
};
}).ToArray());
return pingResult;
}
}
}
48 changes: 48 additions & 0 deletions valentia/Functions/Helper/Credential/Remove-ValentiaCredential.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#Requires -Version 3.0

function Remove-ValentiaCredential
{
[CmdletBinding()]
param
(
[Parameter(mandatory = $false, position = 0)]
[ValidateNotNullOrEmpty()]
[string]$TargetName = $valentia.name,

[Parameter(mandatory = $false, position = 1)]
[ValidateNotNullOrEmpty()]
[ValentiaWindowsCredentialManagerType]$Type = [ValentiaWindowsCredentialManagerType]::Generic
)

try
{
$private:CSPath = Join-Path $valentia.modulePath $valentia.cSharpPath -Resolve
$private:CredReadCS = Join-Path $CSPath CredRead.cs -Resolve
$private:sig = Get-Content -Path $CredReadCS -Raw

$private:addType = @{
MemberDefinition = $sig
Namespace = "Advapi32"
Name = "Util"
}
Add-ValentiaTypeMemberDefinition @addType -PassThru `
| select -First 1 `
| %{
$CredentialType = $_.AssemblyQualifiedName -as [type]
$private:typeFullName = $_.FullName
}

$private:nCredPtr= New-Object IntPtr
if ($CredentialType::CredDelete($TargetName, $Type.value__, 0))
{
}
else
{
throw "No credentials found in Windows Credential Manager for TargetName: '{0}' with Type '{1}'" -f $TargetName, $Type
}
}
catch
{
throw $_
}
}
26 changes: 26 additions & 0 deletions valentia/Functions/Helper/Credential/Test-ValentiaCredential.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#Requires -Version 3.0

function Test-ValentiaCredential
{
[CmdletBinding()]
param
(
[Parameter(mandatory = $false, position = 0)]
[ValidateNotNullOrEmpty()]
[string]$TargetName = $valentia.name,

[Parameter(mandatory = $false, position = 1)]
[ValidateNotNullOrEmpty()]
[ValentiaWindowsCredentialManagerType]$Type = [ValentiaWindowsCredentialManagerType]::Generic
)

try
{
$result = Get-ValentiaCredential -TargetName $targetName
return $true;
}
catch
{
return $false;
}
}
76 changes: 14 additions & 62 deletions valentia/Functions/Invokation/Ping/Ping-ValentiaGroupAsync.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ Ping-ValentiaGroupAsync production-hoge.ps1
--------------------------------------------
Ping production-hoge.ps1 from deploy group branch path
#>

function Ping-ValentiaGroupAsync
{
[OutputType([PingEx.PingResponse[]])]
[CmdletBinding()]
param
(
Expand All @@ -32,85 +34,35 @@ function Ping-ValentiaGroupAsync
[ValidateNotNullOrEmpty()]
[int]$Timeout = $valentia.ping.timeout,

[Parameter(Position = 2, mandatory = $false, HelpMessage = "Input buffer size for the data size send/recieve with ICMP send.")]
[ValidateNotNullOrEmpty()]
[byte[]]$Buffer = $valentia.ping.buffer,

[Parameter(Position = 3, mandatory = $false, HelpMessage = "Input ttl for the ping option.")]
[Parameter(Position = 2, mandatory = $false, HelpMessage = "Input timeout ms wait for the responce answer.")]
[ValidateNotNullOrEmpty()]
[int]$Ttl = $valentia.ping.pingOption.ttl,
[int]$DnsTimeout = $valentia.ping.timeout,

[Parameter(Position = 4, mandatory = $false, HelpMessage = "Input dontFragment for the ping option.")]
[ValidateNotNullOrEmpty()]
[bool]$dontFragment = $valentia.ping.pingOption.dontfragment,

[Parameter(Position = 5, mandatory = $false, HelpMessage = "Change return type to bool only.")]
[Parameter(Position = 3, mandatory = $false, HelpMessage = "Change return type to bool only.")]
[ValidateNotNullOrEmpty()]
[switch]$quiet
)

begin
{
# Preference
$script:ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom

# new object for event and job
$pingOptions = New-Object Net.NetworkInformation.PingOptions($Ttl, $dontFragment)
$tasks = New-Object System.Collections.Generic.List[PSCustomObject]
$output = New-Object System.Collections.Generic.List[PSCustomObject]
$list = New-Object System.Collections.Generic.List["string"];
}

process
{
foreach ($hostNameOrAddress in $HostNameOrAddresses)
{
$ping = New-Object System.Net.NetworkInformation.Ping

("Execute SendPingAsync to host '{0}'." -f $hostNameOrAddress) | Write-ValentiaVerboseDebug
$PingReply = $ping.SendPingAsync($hostNameOrAddress, $timeout, $buffer, $pingOptions)

$task = [PSCustomObject]@{
HostNameOrAddress = $hostNameOrAddress
Task = $PingReply
Ping = $ping}
$tasks.Add($task)
}
$target = (Get-ValentiaGroup -DeployGroup $HostNameOrAddresses);
foreach ($item in $target){ $list.Add($item); }
}

end
{
"WaitAll for Task PingReply have been completed." | Write-ValentiaVerboseDebug
[System.Threading.Tasks.Task]::WaitAll($tasks.Task)

foreach ($task in $tasks)
if ($quiet)
{
try
{
[System.Net.NetworkInformation.PingReply]$result = $task.Task.Result

if (-not ($PSBoundParameters.ContainsKey("quiet") -and $quiet))
{
[PSCustomObject]@{
Id = $task.Task.Id
HostNameOrAddress = $task.HostNameOrAddress
Status = $result.Status
IsSuccess = $result.Status -eq [Net.NetworkInformation.IPStatus]::Success
RoundtripTime = $result.RoundtripTime
}
}
else
{
$result.Status -eq [Net.NetworkInformation.IPStatus]::Success
}
}
finally
{
"Dispose Ping Object" | Write-ValentiaVerboseDebug
if ($null -ne $task){ $task.Ping.Dispose() }

"Dispose PingReply Object" | Write-ValentiaVerboseDebug
if ($null -ne $task){ $task.Task.Dispose() }
}
[PingEx.NetworkInformationExtensions]::PingAsync($list, [TimeSpan]::FromMilliseconds($Timeout), [TimeSpan]::FromMilliseconds($DnsTimeout)).Result.Status;
}
else
{
[PingEx.NetworkInformationExtensions]::PingAsync($list, [TimeSpan]::FromMilliseconds($Timeout), [TimeSpan]::FromMilliseconds($DnsTimeout)).Result;
}
}
}
4 changes: 3 additions & 1 deletion valentia/Tools/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ $valentia.combineTempfunction = '{0}.ps1' -f $valentia.name
$valentia.combineTemptype = 'Type.ps1'
$valentia.fileEncode = [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]'utf8'

$valentia.moduleVersion = "0.4.15"
$valentia.moduleVersion = "0.5.0"
$valentia.description = "PowerShell Remote deployment library for Windows Servers";
$valentia.copyright = "28/June/2013 -"
$valentia.RequiredModules = @()
Expand Down Expand Up @@ -102,7 +102,9 @@ $valentia.functionToExport = @(

# Credential
"Get-ValentiaCredential",
"Remove-ValentiaCredential",
"Set-ValentiaCredential",
"Test-ValentiaCredential",

# DNS
'Get-ValentiaHostEntryAsync',
Expand Down
Loading

0 comments on commit 506752d

Please sign in to comment.