by oising
14. August 2009 02:06
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!
by oising
2. December 2008 22:21
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.
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!
- [Cmdlet(VerbsCommon.Get, "OSVersion")]
- public class GetOSVersionCommand : PSCmdlet, IDynamicParameters
- {
- private const string SWITCH_VISTA = "EnsureElevated";
- private const string SWITCH_WINXP = "EnsureAdministrator";
-
- protected override void EndProcessing()
- {
- WriteObject(Environment.OSVersion);
-
- string switchName = IsVistaOrHigher() ?
- SWITCH_VISTA : SWITCH_WINXP;
-
-
- WriteWarning(String.Format("{0}.IsPresent {1}",
- switchName, IsSwitchPresent(switchName)));
- }
-
-
- public object GetDynamicParameters()
- {
- if (IsVistaOrHigher())
- {
- return new VistaParameters();
- }
- else
- {
- return new WinXPParameters();
- }
- }
-
- private bool IsSwitchPresent(string name)
- {
-
- Dictionary<string, object> parameters = MyInvocation.BoundParameters;
-
-
- if (parameters.ContainsKey(name))
- {
- return ((SwitchParameter) parameters[name]).IsPresent;
- }
- return false;
- }
-
- private static bool IsVistaOrHigher()
- {
- return (Environment.OSVersion.Version.Major >= 6);
- }
-
-
- internal class VistaParameters
- {
- [Parameter]
- public SwitchParameter EnsureElevated
- {
- get; set;
- }
- }
-
-
-
- internal class WinXPParameters
- {
- [Parameter]
- public SwitchParameter EnsureAdministrator
- {
- get; set;
- }
- }
- }
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.
by oising
5. September 2008 20:13
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):
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!
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.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
- $principal = new-object Security.Principal.WindowsPrincipal $identity
- $elevated = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
-
- if (-not $elevated) {
- $error = "Sorry, you need to run this script"
- if ([System.Environment]::OSVersion.Version.Major -gt 5) {
- $error += " in an elevated shell."
- } else {
- $error += " as Administrator."
- }
- throw $error
- }
-
- function confirm {
- $host.ui.PromptForChoice("Continue", "Process adapter?",
- [Management.Automation.Host.ChoiceDescription[]]@("&No", "&Yes"), 0) -eq $true
- }
-
-
- pushd 'hklm:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}'
-
-
- dir -ea 0 | % {
- $node = $_.pspath
- $desc = gp $node -name driverdesc
- if ($desc -like "*vmware*") {
- write-host ("Found adapter: {0} " -f $desc.driverdesc)
- if (confirm) {
- new-itemproperty $node -name '*NdisDeviceType' -propertytype dword -value 1
- }
- }
- }
- popd
-
-
- gwmi win32_networkadapter | ? {$_.name -like "*vmware*" } | % {
-
-
- write-host -nonew "Disabling $($_.name) ... "
- $result = $_.Disable()
- if ($result.ReturnValue -eq -0) { write-host " success." } else { write-host " failed." }
-
-
- write-host -nonew "Enabling $($_.name) ... "
- $result = $_.Enable()
- if ($result.ReturnValue -eq -0) { write-host " success." } else { write-host " failed." }
- }
Have fun.