PowerShell for Windows Admins


June 2, 2012  7:58 AM

Using a colon with cmdlet parameters

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Another question at Tuesdays PowerShell group revolved around using colons to link values to parameters. I’d not really thought about before. Thinking about it  later I realised that you only really see it when passing booleans to –Confirm.  If you don’t use a colon then you get this

PS> Disable-NetAdapter -Name "Virtual Wireless" -Confirm $false
Disable-NetAdapter : A positional parameter cannot be found that accepts argument ‘False’.
At line:1 char:1
+ Disable-NetAdapter -Name "Virtual Wireless" -Confirm $false
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Disable-NetAdapter], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Disable-NetAdapter

But this will work

PS> Disable-NetAdapter -Name "Virtual Wireless" -Confirm:$false

Just for completeness this works as well

PS> Get-NetAdapter –Name:"Virtual Wireless" 

though it doesn’t tend to get used

June 2, 2012  6:34 AM

Using Windows 2012 Active Directory module in a Windows 2008 R2 domain

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A question came up on Tuesdays UK PowerShell Group session about using the Windows 2012 Active Directory module. The recording links are here

http://msmvps.com/blogs/richardsiddaway/archive/2012/05/30/may-2012-powershell-group-recording-and-slides.aspx

The question asked if the new Site, Subnet and Site link cmdlets would work in a legacy environment.

This morning I installed a Windows Server 2012 Release Candidate member server into my Windows 2008 R2 domain. I then installed the RSAT feature on the Windows 2012 server – this includes the Active Directory module.

The site, subnet and site link cmdlets appear to work with NO changes required to the Windows 2008 R2 domain controller. I was able to view and create sites, subnets and site links.

I haven’t tested any other scenario.


June 2, 2012  3:07 AM

PowerShell v3 release candidate

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Hot on the heels of the Windows 8/2012 release candidates comes the PowerShell v3 (well Ok the Windows Management Framework) release candidate.

This is available for

  • Windows 7 SP 1
  • Windows Server 2008 R2 SP 1
  • Windows 2008 SP2

32 and 64 bit versions are available as applicable to the OS

Notice the omissions Vista, Windows 2003 and XP. If that continues into RTM there will be some issues around using the some of the functionality across the estate as it relies on WSMAN 3.0

Details and links from here

http://blogs.msdn.com/b/powershell/archive/2012/06/02/windows-management-framework-3-0-rc-is-available-for-download.aspx


June 1, 2012  1:07 PM

Working with profiles: part 1

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A question came up on the forum for PowerShell and WMI – how do I delete profiles. I’m going to work up to answering that by looking at using WMI to work with profiles.

So to start how can we find the profiles available on our system

Get-WmiObject -Class Win32_UserProfile |
select LocalPath, SID, @{N="LastUseTime"; E={$_.ConvertToDateTime($_.LastUseTime)}}

LocalPath                   SID                         LastUseTime              
———                   —                         ———–              
C:\Users\Richard            S-1-5-21-2542198769-1191… 01/06/2012 19:56:28      
C:\Windows\ServiceProfil… S-1-5-20                                             
C:\Windows\ServiceProfil… S-1-5-19                                             
C:\Windows\system32\conf… S-1-5-18        

or if you prefer the CIM cmdlets in PowerShell v3

Get-CimInstance -ClassName Win32_UserProfile |
select LocalPath, SID, LastUseTime

C:\Users\Richard            S-1-5-21-2542198769-1191… 01/06/2012 19:56:28      
C:\Windows\ServiceProfil… S-1-5-20                                             
C:\Windows\ServiceProfil… S-1-5-19                                             
C:\Windows\system32\conf… S-1-5-18
   

Notice that with the CIM cmdlet we don’t have to perform any date conversions – worth switching just for that alone.

But the data above doesn’t show the user account.

Unfortunately there isn’t an association between profile and user account so we need to do the filtering ourselves

Get-WmiObject -Class Win32_UserProfile |
select LocalPath, SID,
@{N="LastUseTime"; E={$_.ConvertToDateTime($_.LastUseTime)}},
@{N="User"; E={Get-WmiObject -Class Win32_UserAccount -Filter "SID = ‘$($_.SID)’" | select -ExpandProperty Caption}}

LocalPath            SID                  LastUseTime          User              
———            —                  ———–          —-              
C:\Users\Richard     S-1-5-21-25421987… 01/06/2012 20:01:56  RSLAPTOP01\Richard
C:\Windows\Servic… S-1-5-20                                                    
C:\Windows\Servic… S-1-5-19                                                    
C:\Windows\system… S-1-5-18   

The alternative with the CIM cmdlets

Get-CimInstance -ClassName Win32_UserProfile |
select LocalPath, SID, LastUseTime,
@{N="User"; E={Get-CimInstance -Class Win32_UserAccount -Filter "SID = ‘$($_.SID)’" |
select -ExpandProperty Caption}}

C:\Users\Richard     S-1-5-21-25421987… 01/06/2012 20:01:56  RSLAPTOP01\Richard
C:\Windows\Servic… S-1-5-20                                                    
C:\Windows\Servic… S-1-5-19                                                    
C:\Windows\system… S-1-5-18  

The final part is to filter out any of the well known special accounts such as Local service

Get-WmiObject -Class Win32_UserProfile -Filter "Special = ‘$false’" |
select LocalPath, SID,
@{N="LastUseTime"; E={$_.ConvertToDateTime($_.LastUseTime)}},
@{N="User"; E={Get-WmiObject -Class Win32_UserAccount -Filter "SID = ‘$($_.SID)’" | select -ExpandProperty Caption}}

or

Get-CimInstance -ClassName Win32_UserProfile -Filter "Special = ‘$false’" |
select LocalPath, SID, LastUseTime,
@{N="User"; E={Get-CimInstance -Class Win32_UserAccount -Filter "SID = ‘$($_.SID)’" | select -ExpandProperty Caption}}

either of these will just return the top line in the output above.

Now we can identify our profiles & relate them to user accounts – how do we delete them


May 30, 2012  1:03 PM

May 2012 Powershell group recording and slides

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

 

The recording, slides and demo scripts from last nights session  – Powershell in Windows Server 8 part 2  – is available from

https://skydrive.live.com/?cid=43cfa46a74cf3e96#cid=43CFA46A74CF3E96&id=43CFA46A74CF3E96%212966

The full set of historical recordings can be found here:

https://skydrive.live.com/#cid=43CFA46A74CF3E96&id=43CFA46A74CF3E96%212469

2011 09 PowerShell remoting and end point customisation
2011 11 Whats new in PowerCLI 5
2011 12 Intro to WMI
2011 12 WSMAN_WMI_and_CIM
2012 January PowerShell v3 CTP 2 overview
2012 February PowerShell and SQL Server
2012 March CIM cmdlets
2012 April Powershell in Windows Server 8
2012 May Powershell in Windows Server 8 part 2 

Older folders just have the slides


May 27, 2012  10:56 AM

May UG meeting reminder

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Quick reminder that the UK PowerShell group session on PowerShell in Windows 2012 is on Tuesday 29 May. Details from

http://msmvps.com/blogs/richardsiddaway/archive/2012/05/08/uk-powershell-group-may-2012.aspx


May 25, 2012  11:58 AM

Working with WMI methods

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Many WMI classes have methods. Methods allow us to perform some action on the object. A recent question on the forum about using methods made me realise that there are still a lot of people following the old VBScript way of doing things.

We will experiment with the BITS service as it is safe for these purposes.

PS> Get-WmiObject -Class Win32_Service -Filter "Name = ‘BITS’"

ExitCode  : 0
Name      : BITS
ProcessId : 928
StartMode : Auto
State     : Running
Status    : OK

Lets have a look at the service and its methods

$service = Get-WmiObject -Class Win32_Service -Filter "Name = ‘BITS’"

$service | Get-Member -MemberType method

TypeName: System.Management.ManagementObject#root\cimv2\Win32_Service

Name
—-
Change
ChangeStartMode
Delete
GetSecurityDescriptor
InterrogateService
PauseService
ResumeService
SetSecurityDescriptor
StartService
StopService
UserControlService

So we see methods to stop and start the service

$service.StopService()

PS> Get-Service BITS

Status   Name               DisplayName
——   —-               ———–
Stopped  BITS               Background Intelligent Transfer Ser…

$service.StartService()

PS> Get-Service BITS

Status   Name               DisplayName
——   —-               ———–
Running  BITS               Background Intelligent Transfer Ser…

The person asking the question was trying to use the InvokeMethod method

$service.InvokeMethod(‘StopService’,$Null)

and wondering why it was failing. If you look back to the list of methods above you won’t see InvokeMethod. That’s because it is on the base object. PowerShell, in many instances, doesn’t return the pure .NET object. There are methods and properties added or removed to create the object we normally see.

We can get back to the base object

$service.psbase | gm

And in that list you will see a method called InvokeMethod

PS> $service.psbase.InvokeMethod

OverloadDefinitions
——————-
System.Object InvokeMethod(string methodName, System.Object[] args)
void InvokeMethod(System.Management.ManagementOperationObserver watcher, string methodName, System.Object[] args)
System.Management.ManagementBaseObject InvokeMethod(string methodName, System.Management.ManagementBaseObject
inParameters, System.Management.InvokeMethodOptions options)
void InvokeMethod(System.Management.ManagementOperationObserver watcher, string methodName,
System.Management.ManagementBaseObject inParameters, System.Management.InvokeMethodOptions options)

Shows us how to use it.

Going for the simplest option

PS> $service.psbase.InvokeMethod("StopService", $null)
0
PS> Get-Service BITS

Status   Name               DisplayName
——   —-               ———–
Stopped  BITS               Background Intelligent Transfer Ser…

PS> $service.psbase.InvokeMethod("StartService", $null)
0
PS> Get-Service BITS

Status   Name               DisplayName
——   —-               ———–
Running  BITS               Background Intelligent Transfer Ser…

PS> Get-WmiObject -Class Win32_Service -Filter "Name = ‘BITS’" | Invoke-WmiMethod -Name StopService

PS> Get-Service BITS

Status   Name               DisplayName
——   —-               ———–
Stopped  BITS               Background Intelligent Transfer Ser…

PS> Get-WmiObject -Class Win32_Service -Filter "Name = ‘BITS’" | Invoke-WmiMethod -Name StartService

PS> Get-Service BITS

Status   Name               DisplayName
——   —-               ———–
Running  BITS               Background Intelligent Transfer Ser…

These options will work as well

$service | Invoke-WmiMethod -Name StopService
$service | Invoke-WmiMethod -Name StartService

Invoke-WmiMethod -InputObject $service -Name StopService
Invoke-WmiMethod -InputObject $service -Name StartService

My preference is to use the get-wmiobject | invoke-wmimethod pairing as when I am developing I can easily test any filters before I start affecting the service.

Of all of the options using the  InvokeMethod method is the one to avoid as it is more cumbersome and involves more typing

In PowerShell v3 we can use the CIM cmdlets but that is a post for another day

More information on using WMI with PowerShell in PowerShell and WMI – www.manning.com/powershellandwmi


May 23, 2012  12:46 PM

WMI providers

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I found a class new to me – Msft_Providers and this got me interested in WMI providers.

PS> Get-CimInstance -Class Msft_Providers | select -ExpandProperty provider
Msft_ProviderSubSystem
SCM Event Provider
WmiPerfClass

 

That seems a bit low. Digging a bit more I got back to the old favourite __provider.

Get-CimInstance -Class __provider | Measure-Object

produces an answer of 43 – not quite the answer to life, the universe and everything but close.

Is there any overlap between the two groups of providers?

 

$providers = Get-CimInstance -Class Msft_Providers | select -ExpandProperty provider           
Get-CimInstance -Class __provider | where Name -in $providers | select Name

 

provides the answer

Msft_ProviderSubSystem  

SCM Event Provider

 

In case you were wondering – “Starting with Windows Vista, the WMIPerfClass Provider and the WMIPerfInst Provider dynamically provide performance counter data for the WMI Performance Counter Classes.”

see http://msdn.microsoft.com/en-us/library/windows/desktop/aa392740(v=vs.85).aspx

 

One interesting property is the Hosting Model

Get-CimInstance -Class __provider | select HostingModel -Unique

Decoupled:NonCOM
NetworkServiceHost
WmiCore
LocalSystemHost
LocalServiceHost

NetworkServiceHost:[ReliabilityMetricsProvider]

 

But what do these mean

Full explanations for these and the other hosting models can be found at

http://msdn.microsoft.com/en-us/library/aa392509(VS.85).aspx

WmiCore – Activate provider in host to the WMI service. This hosting model is only supported for operating system components.

WmiCoreOrSelfHost – Activate provider in host to the WMI service or as local server. This hosting model is only supported for operating system components.

SelfHost – Activate provider as a local server implementation.

Decoupled:Com – Activate provider as a decoupled COM provider. See http://msdn.microsoft.com/en-us/library/aa390882(v=vs.85).aspx
 
Decoupled:NonCom – Activate provider as a non-COM event provider.
 
LocalSystemHost – Activate provider in the provider host process that is running under the LocalSystem account.

LocalSystemHostOrSelfHost – The provider is self-hosted or loaded into the Wmiprvse.exe process running under the LocalSystem account.

NetworkServiceHost – Activate provider in the provider host process that is running under the NetworkService account.

LocalServiceHost – Activate provider in the provider host process that is running under the LocalService account.

NetworkServiceHostOrSelfHost – The provider is self-hosted or loaded into the WmiPrvse.exe process running under the NetworkService account. NetworkServiceHostOrSelfHost is the default configuration when the HostingModel property in __Win32Provider is NULL. Because NetworkServiceHostOrSelfHost is the default, providers from earlier operating systems can continue to work in Windows Vista, Windows Server 2008, and later operating systems.

Get-CIMInstance is a new cmdlet in PowerShell v3. It is part of the new API for working with WMI. I will be blogging about these in greater detail over the next weeks and months as Powershell v3 is released.

More information on providers and the CIM cmdlets can be found in PowerShell and WMIwww.manning.com/powershellandwmi


May 21, 2012  1:56 PM

UK PowerShell group–next two meetings

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

29 May 2012

PowerShell and Windows server 2012 – new functionality pt 2

http://msmvps.com/blogs/richardsiddaway/archive/2012/05/08/uk-powershell-group-may-2012.aspx

 

4 July

Jonathan Medd

XenDesktop and PowerShell

This will be at the slightly later time of 8.30 BST.  Details to follow


May 20, 2012  12:40 PM

Using Invoke-WmiMethod to set the DNS servers

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

In the last post I showed that there was an issue with the way the SetDNSServerSearchOrder of the Win32_NetworkAdapterConfiguration class worked

This would work

$nic = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "Index=7"
$nic.SetDNSServerSearchOrder("10.10.54.201")

but using Invoke-WmiMethod failed

After discussions with Bartek Bielawski (PowerShell MVP) and a bit more digging I found that for multiple DNS servers this would work

$dnsserver = "10.10.54.201", "10.10.54.98"
Get-WmiObject -Class Win32_NetworkAdapterConfiguration  -Filter "Index=7" | Invoke-WmiMethod -Name SetDNSServerSearchOrder -ArgumentList (, $dnsserver)

Its necessary to create an array as the input argument  (, $variable) – its a unary array ie one element array

if you want to use just a single DNS server then you need to use the unary array trick twice – once when you create the variable and again when you use Invoke-wmimethod.  Messy but it works

$dnsserver = (,"10.10.54.201")
Get-WmiObject -Class Win32_NetworkAdapterConfiguration  -Filter "Index=7" | Invoke-WmiMethod -Name SetDNSServerSearchOrder -ArgumentList (, $dnsserver)

 

If you want to use the new CIM cmdlets in PowerShell v3 – its easy if you have multiple DNS servers

$dnsserver = "10.10.54.201", "10.10.54.98"
Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "Index=7" | Invoke-CimMethod -MethodName SetDNSServerSearchOrder -Arguments @{DNSServerSearchOrder = $dnsserver}

 

for a single one we just need to create a unary array on the Arguments parameter
$dnsserver = "10.10.54.201"
Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "Index=7" | Invoke-CimMethod -MethodName SetDNSServerSearchOrder -Arguments @{DNSServerSearchOrder = (,$dnsserver)}

 

This is not satisfactory because we have to adopt different techniques depending on the number of DNS servers we need to put into NIC property. This is NOT a PowerShell issue – it has to be a WMI issue because the IP address that we saw last time also takes an array and it was very happy with a single value.

Hopefully this is not something that will come up too often but be aware of these options when working with WMI methods


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: