# Thursday, August 13, 2009

I’ve been reliably informed (and double checked) and I’m happy to relay to you all that PowerShell 2.0 is available as part of the Windows Management Framework RC. This includes the following components:

  • WinRM 2.0
  • Windows PowerShell 2.0
  • BITS 4.0

This is the culmination of nearly three years’ of work to bring Windows to the cutting edge of automation technology. Grab it while it’s toasty from:

https://connect.microsoft.com/windowsmanagement/Downloads

Spread the word!

posted on Thursday, August 13, 2009 10:06:02 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Tuesday, December 02, 2008

Normally parameters for a Cmdlet are defined directly as properties on the Cmdlet class itself. There are a few other ways for a Cmdlet to define parameters, and in this short series of three parts, I’ll cover the three variants you’ll likely to encounter as you become a more experienced PowerShell developer. First thing you need to do is to implement the System.Management.Automation.IDynamicParameters interface on your Cmdlet. This interface has one member, GetDynamicParameters. This interface can be implemented on either a Provider or a Cmdlet. In the former case, a provider is able to add new parameters at runtime to certain built-in Cmdlets like Get-ChildItem, Get-Item & Get-ItemProperty. It is typically used in a path context-aware manner – e.g. depending on whether the current argument is a folder or item, and what Type such a folder or item might be. We’re just to cover the Cmdlet variant in this post.

image

My example is just a simple Cmdlet named Get-OSVersion. It writes out Environment.OSVersion to the pipeline, and will dynamically add a parameter. It adds –EnsureElevated if you’re running Vista or higher, otherwise it will add –EnsureAdministrator. Statically defined dynamic parameter sets are defined by creating a simple class and decorating that class with parameter/properties you want to surface as if that class was the Cmdlet itself, then returning it from the GetDynamicProperties method at runtime. Simple!

  1. [Cmdlet(VerbsCommon.Get, "OSVersion")]   
  2. public class GetOSVersionCommand : PSCmdlet, IDynamicParameters   
  3. {   
  4.     private const string SWITCH_VISTA = "EnsureElevated";   
  5.     private const string SWITCH_WINXP = "EnsureAdministrator";   
  6.   
  7.     protected override void EndProcessing()   
  8.     {   
  9.         WriteObject(Environment.OSVersion);   
  10.            
  11.         string switchName = IsVistaOrHigher() ?   
  12.             SWITCH_VISTA : SWITCH_WINXP;   
  13.   
  14.         // not really a warning, just nice yellow text.   
  15.         WriteWarning(String.Format("{0}.IsPresent {1}",   
  16.             switchName, IsSwitchPresent(switchName)));   
  17.     }   
  18.   
  19.     // IDynamicParameters.GetDynamicParameters   
  20.     public object GetDynamicParameters()   
  21.     {   
  22.         if (IsVistaOrHigher())   
  23.         {   
  24.             return new VistaParameters();   
  25.         }   
  26.         else  
  27.         {   
  28.             return new WinXPParameters();   
  29.         }   
  30.     }   
  31.        
  32.     private bool IsSwitchPresent(string name)   
  33.     {   
  34.         // parameters bound at runtime   
  35.         Dictionary<stringobject> parameters = MyInvocation.BoundParameters;   
  36.   
  37.         // determine whether switch is set   
  38.         if (parameters.ContainsKey(name))   
  39.         {   
  40.             return ((SwitchParameter) parameters[name]).IsPresent;   
  41.         }   
  42.         return false;   
  43.     }   
  44.   
  45.     private static bool IsVistaOrHigher()   
  46.     {   
  47.         return (Environment.OSVersion.Version.Major >= 6);   
  48.     }   
  49.   
  50.     // dynamic parameters for Vista   
  51.     internal class VistaParameters   
  52.     {   
  53.         [Parameter]   
  54.         public SwitchParameter EnsureElevated   
  55.         {   
  56.             getset;   
  57.         }   
  58.     }   
  59.   
  60.     // dynamic parameters for Windows XP   
  61.     // (powershell won't run on windows 2000 ;-))   
  62.     internal class WinXPParameters   
  63.     {   
  64.         [Parameter]   
  65.         public SwitchParameter EnsureAdministrator   
  66.         {   
  67.             getset;   
  68.         }   
  69.     }   
  70. }  

Of course, adding Dynamic Parameters is no good if you don’t know how to read them back. In the code, you can see I’m using MyInvocation.BoundParameters to check if the Switches have been set.

posted on Tuesday, December 02, 2008 5:21:10 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] Trackback
# Friday, September 05, 2008

Are you sick and tired of switching the VMWare virtual network adapters from the “public” network profile to a “private” network profile each time you reboot or do something else that causes Vista/Win2008 to forget what you told it to do ten minutes ago? This is probably a familiar sigh (I’m using Workstation):

vmware-unidentified-network

As you can see, the lower two connections are seen to be in a “Public network.” This has the net effect of making Windows believe the whole machine is exposed to a public network, and it will trigger the public profile for Windows Firewall. This is normally a good thing, but in this case it’s just an annoyance. These two network connections are not actually external gateways that can let in the bad guys. They are just dummy adapters for VMWare’s host bridging which allow the virtual machine to access the host machine’s network. Because they don’t identify themselves properly, they are flagged as an “unidentified network,” and your changes are never persisted.

So what do you do? The magic information is buried in MSDN:

Vista automatically identifies and monitors the networks to which a computer connects. If the NDIS_DEVICE_TYPE_ENDPOINT flag is set, the device is an endpoint device and is not a connection to a true external network. Consequently, Windows ignores the endpoint device when Windows identifies networks. The Network Awareness APIs indicate that the device does not connect the computer to a network. For end users in this situation, the Network and Sharing Center and the network icon in the notification area do not show the NDIS endpoint device as connected. However, the connection is shown in the Network Connections Folder. Also, if NDIS_DEVICE_TYPE_ENDPOINT is set, the Windows Firewall ignores the connection when Windows Firewall enforces public, private, or domain policies.

So I hacked together a PowerShell script that will scan your adapters for VMWare’s virtual NICs and make the necessary registry changes. It will also disable/enable cycle the adapters so that the changes take effect. After this is done, you will see them in your Network Connections page – albeit lacking a network category -- and the connections will no longer appear in the Network and Sharing Center nor will they affect your Windows Firewall policy no matter how many times you reboot!

vmware-unidentified-network-1

Here’s the script source below. It requires that you run it in an elevated shell in order to write the registry changes and cycle the adapters’ enabled state.

  1. # see http://msdn2.microsoft.com/en-us/library/bb201634.aspx  
  2. #  
  3. # *NdisDeviceType   
  4. #  
  5. # The type of the device. The default value is zero, which indicates a standard  
  6. # networking device that connects to a network.  
  7. #  
  8. # Set *NdisDeviceType to NDIS_DEVICE_TYPE_ENDPOINT (1) if this device is an  
  9. # endpoint device and is not a true network interface that connects to a network.  
  10. # For example, you must specify NDIS_DEVICE_TYPE_ENDPOINT for devices such as  
  11. # smart phones that use a networking infrastructure to communicate to the local  
  12. # computer system but do not provide connectivity to an external network.   
  13. #  
  14. # Usage: run in an elevated shell (vista/longhorn) or as adminstrator (xp/2003).  
  15. #  
  16. # PS> .\fix-vmnet-adapters.ps1  
  17.  
  18. # boilerplate elevation check  
  19.  
  20. $identity = [Security.Principal.WindowsIdentity]::GetCurrent()  
  21. $principal = new-object Security.Principal.WindowsPrincipal $identity 
  22. $elevated = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)  
  23.  
  24. if (-not $elevated) {  
  25.     $error = "Sorry, you need to run this script" 
  26.     if ([System.Environment]::OSVersion.Version.Major -gt 5) {  
  27.         $error += " in an elevated shell." 
  28.     } else {  
  29.         $error += " as Administrator." 
  30.     }  
  31.     throw $error 
  32. }  
  33.  
  34. function confirm {  
  35.     $host.ui.PromptForChoice("Continue", "Process adapter?",  
  36.         [Management.Automation.Host.ChoiceDescription[]]@("&No", "&Yes"), 0) -eq $true 
  37. }  
  38.  
  39. # adapters key  
  40. pushd 'hklm:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}' 
  41.  
  42. # ignore and continue on error  
  43. dir -ea 0  | % {  
  44.     $node = $_.pspath  
  45.     $desc = gp $node -name driverdesc  
  46.     if ($desc -like "*vmware*") {  
  47.         write-host ("Found adapter: {0} " -f $desc.driverdesc)  
  48.         if (confirm) {  
  49.             new-itemproperty $node -name '*NdisDeviceType' -propertytype dword -value 1  
  50.         }  
  51.     }  
  52. }  
  53. popd  
  54.  
  55. # disable/enable network adapters  
  56. gwmi win32_networkadapter | ? {$_.name -like "*vmware*" } | % {  
  57.       
  58.     # disable  
  59.     write-host -nonew "Disabling $($_.name) ... " 
  60.     $result = $_.Disable()  
  61.     if ($result.ReturnValue -eq -0) { write-host " success." } else { write-host " failed." }  
  62.       
  63.     # enable  
  64.     write-host -nonew "Enabling $($_.name) ... " 
  65.     $result = $_.Enable()  
  66.     if ($result.ReturnValue -eq -0) { write-host " success." } else { write-host " failed." }  
  67. }  

Have fun.

posted on Friday, September 05, 2008 4:13:52 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [1] Trackback