Created
September 16, 2015 21:54
-
-
Save IISResetMe/3c3e9408129af6a928f5 to your computer and use it in GitHub Desktop.
Offline comments for Richard Siddaway's Objective: Objects talk @ PSHSummit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region new() | |
# new() works not only on PS Classes, but wraps existing .NET ctors as well: | |
[System.Net.WebProxy]::new("proxyserver.contoso.com",3128) | |
#endregion | |
#region Add-Type | |
#region Access modifiers | |
# Add-Type and C# type and member defitions are not only useful for controlling accessibility levels: | |
$Definition = @' | |
public class MyClass { | |
public string param1 { get; set; } | |
private string param2 { get; set; } | |
public MyClass() { | |
this.param2 = "Not accessible from outside the class"; | |
} | |
} | |
'@ | |
Add-Type -TypeDefinition $Definition | |
#endregion | |
#region property accessors | |
# But for defining custom accessors ("getters" and "setters") as well: | |
$Definition = @' | |
public class MyMathClass { | |
private int square; | |
public int Square | |
{ | |
get { return this.square; } | |
set { this.square = value * value; } | |
} | |
} | |
'@ | |
Add-Type -TypeDefinition $Definition | |
# What black magic is this?! | |
PS C:\> $myInstance = [MyMathClass]::new() | |
PS C:\> $myInstance.Square = 3 | |
PS C:\> $myInstance.Square | |
9 | |
#endregion | |
#region DllImport | |
# and finally: marshalling native code! | |
# PowerShell + the DllImport attribute + pinvoke.net = magic | |
$PingUtilityDefinition = @' | |
using System; | |
using System.Net; | |
using System.Runtime.InteropServices; | |
public class IcmpPing | |
{ | |
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] | |
private struct ICMP_OPTIONS | |
{ | |
public byte Ttl; | |
public byte Tos; | |
public byte Flags; | |
public byte OptionsSize; | |
public IntPtr OptionsData; | |
} | |
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] | |
private struct ICMP_ECHO_REPLY | |
{ | |
public int Address; | |
public int Status; | |
public int RoundTripTime; | |
public short DataSize; | |
public short Reserved; | |
public IntPtr DataPtr; | |
public ICMP_OPTIONS Options; | |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=250)] | |
public string Data; | |
} | |
[DllImport("icmp.dll", SetLastError=true)] | |
private static extern IntPtr IcmpCreateFile(); | |
[DllImport("icmp.dll", SetLastError=true)] | |
private static extern bool IcmpCloseHandle(IntPtr handle); | |
[DllImport("icmp.dll", SetLastError=true)] | |
private static extern int IcmpSendEcho(IntPtr icmpHandle, int destinationAddress, string requestData, short requestSize, ref ICMP_OPTIONS requestOptions, ref ICMP_ECHO_REPLY replyBuffer, int replySize, int timeout); | |
public bool Ping(IPAddress ip) | |
{ | |
IntPtr icmpHandle = IcmpCreateFile(); | |
ICMP_OPTIONS icmpOptions = new ICMP_OPTIONS(); | |
icmpOptions.Ttl = 255; | |
ICMP_ECHO_REPLY icmpReply = new ICMP_ECHO_REPLY(); | |
string sData = "x"; | |
int iReplies = IcmpSendEcho(icmpHandle, BitConverter.ToInt32(ip.GetAddressBytes(), 0), sData, (short)sData.Length, ref icmpOptions, ref icmpReply, Marshal.SizeOf(icmpReply), 30); | |
IcmpCloseHandle(icmpHandle); | |
if (icmpReply.Status == 0) | |
return true; | |
return false; | |
} | |
} | |
'@ | |
Add-Type -TypeDefinition $PingUtilityDefinition | |
# Now you can have the OS send an ICMP echo for you, just like ping.exe - incredibly low overhead: | |
PS C:\> [IcmpPing]::new().Ping("127.0.0.1") | |
True | |
# Example above is from http://pinvoke.net/default.aspx/icmp.IcmpSendEcho | |
#endregion | |
#endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment