PowerShell for Windows Admins


March 22, 2016  12:46 PM

Breaking CIM sessions

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, Powershell

A CIM session is analogous to a PowerShell remoting session but for CIM based cmdlets – the CIM cmdlets themselves and any CDXML based cmdlets e.g. the networking cmdlets

By default a CIM session uses WSMAN as its transport protocol – the same as remoting. You do have the choice to create a CIM session using DCOM for transport (same as the WMI cmdlets use)

I’ve always maintained that DCOM based sessions could be broken if the remote machine was re-started. This was based on the testing I did when writing PowerShell and WMI.

Some recent information cast doubt on that assertion though.  I’ve digging into CIM sessions recently and have what I think is a definitive statement on DCOM based CIM sessions.

If you create a DCOM based CIM session to a machine running PowerShell 2.0 from a machine running PowerShell 3.0 (or PowerShell 4.0 – I haven’t tested recently but remember doing this when writing the CIM section of PowerShell in Depth) access the remote machine and then restart and attempt to use the session – it will break like this:

$dopt = New-CimSessionOption -Protocol Dcom
$dcs = New-CimSession -ComputerName W8R2STD01 -SessionOption $dopt
Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $dcs

SystemDirectory   Organization     BuildNumber      RegisteredUser   SerialNumber     Version          PSComputerName
—————   ————     ———–      ————–   ————     ——-          ————–
C:\Windows\sys…                  7601             Windows User     00477-179-000… 6.1.7601         W8R2STD01
Restart-Computer -ComputerName W8R2STD01
Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $dcs
Get-CimInstance : Access is denied.
At line:1 char:1
+ Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $dcs
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : PermissionDenied: (root\cimv2:Win32_OperatingSystem:String) [Get-CimInstance], CimExcept
ion
+ FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand
+ PSComputerName        : W8R2STD01

The CIM session will usually become usable again after a period of time.

If you repeat the experiment using WSMAN or DCOM sessions to machines running PowerShell 3.0 or above the command to use the session is effectively paused until the session is responsive – this can take a little time

A machine running PowerShell 5.0 RTM can create a CIM session to PowerShell 2.0 (DCOM)  or later (DCOM or WSMAN) and the command is effectively paused until the remote machine is up.

The only time I can see the need to use a DCOM based CIM session is to access a PowerShell 2.0 machine – under any other circumstances I’d recommend using the default WSMAN based sessions.

Bottom line is that DCOM based sessions can be broken under specific circumstances that hopefully with time will disappear.

March 21, 2016  12:35 PM

LocalAccounts module

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell, Windows 10

I’m running Windows 10 and I’m on the fast ring for new Windows 10 builds. Sometimes that’s a good thing and other times its not.

I decided to update help and after the update got a message: Failed to update Help for the module(s) ‘Microsoft.PowerShell.LocalAccounts’

That was a new one to me

I looked at the release notes – https://github.com/PowerShell/PowerShell-Docs/tree/master/undefined

What a dogs breakfast!

I understand why ‘open sourcing’ the release notes but using git hub for release notes is a truly awful experience

Any way I couldn’t find anything about a LocalAccounts module

I need to do some investigation but current the module is at version 1.0.0.0 and contains these cmdlets

Add-LocalGroupMember
Disable-LocalUser
Enable-LocalUser
Get-LocalGroup
Get-LocalGroupMember
Get-LocalUser
New-LocalGroup
New-LocalUser
Remove-LocalGroup
Remove-LocalGroupMember
Remove-LocalUser
Rename-LocalGroup
Rename-LocalUser
Set-LocalGroup
Set-LocalUser


March 20, 2016  5:43 AM

Module Name change NetworkSwitch to NetworkSwitchManager

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Just been caught out by a module name change in WMF 5.0

The NetworkSwitch module has been renamed to NetworkSwitchManager.  Still has the same functionality

Disable-NetworkSwitchEthernetPort
Disable-NetworkSwitchFeature
Disable-NetworkSwitchVlan
Enable-NetworkSwitchEthernetPort
Enable-NetworkSwitchFeature
Enable-NetworkSwitchVlan
Get-NetworkSwitchEthernetPort
Get-NetworkSwitchFeature
Get-NetworkSwitchGlobalData
Get-NetworkSwitchVlan
New-NetworkSwitchVlan
Remove-NetworkSwitchEthernetPortIPAddress
Remove-NetworkSwitchVlan
Restore-NetworkSwitchConfiguration
Save-NetworkSwitchConfiguration
Set-NetworkSwitchEthernetPortIPAddress
Set-NetworkSwitchPortMode
Set-NetworkSwitchPortProperty
Set-NetworkSwitchVlanProperty

One of these days I should read the realease notes  🙂


March 19, 2016  4:56 AM

PowerShell Community in action

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

In response to this post – ttps://richardspowershellblog.wordpress.com/2016/02/29/csv-file-with-in-headers/

Japp Brasser wrote a function to automate header name replacements. You can find the function at https://github.com/jaapbrasser/UtilityScripts/blob/master/Import-CsvFixHeader.ps1

Enjoy


March 18, 2016  6:11 AM

Network adapter Index

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell, WMI

A few years ago I wrote a post about setting the IP metric on a connection – https://richardspowershellblog.wordpress.com/2012/01/01/changing-ip-connection-metric/

I was recently asked if the Index’s associated with network adapters were consistent acros machines. The answer – unfortunately- is no they’re not as a rule.

I used the function from the original post

function Test-IPmetric {
Get-WmiObject -Class Win32_NetworkAdapter -Filter “AdapterType = ‘Ethernet 802.3′” |
foreach {
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter “Index=$($_.DeviceId)” |
Select-Object Description, Index, IPEnabled, IPConnectionMetric
}
}

to view the index

The Index property from Win32_NetworkAdapaterConfiguration is identical to the DeviceId from the Win32_NetworkAdapater class for a given network adapter.

if you try the function on a number of machines you’ll see that Index numbers assigned by Windows aren’t consistent.  My test VMs (Hyper-V) all seem to have the same index numbers assigned but I always create my VMs and add network adapters in the same way.

I wouldn’t rely on a particular index being assigned to a given network adapter – always pull the data and test


March 10, 2016  12:13 PM

Really?

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Been testing things for my container talk at the Summit and opened Internet Explorer on my Server 2012 R2 machine to be greeted by

“Microsoft recommends upgrading to Windows 10”

Forget Server 2016 guys all you need is Windows 10  🙂


March 9, 2016  12:09 PM

PowerShell package management on PowerShell 3 and 4

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

PowerShell 5.0 introduced PackageManagement (Oneget) – for managing software installation packages and PowerShellGet for managing PowerShell modules.

Those features are now available on PowerShell 3 and 4

https://blogs.msdn.microsoft.com/powershell/2016/03/08/package-management-preview-march-2016-for-powershell-4-3-is-now-available/


March 6, 2016  9:28 AM

PowerShell Summit 2016–sold out

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

The last place for the PowerShell Summit has been sold. We’re at capacity so no more places can be made available.

Looking forward to seeing you all there


March 1, 2016  1:56 PM

Comparing lists

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

An interesting question on the forum regarding how you compare the contents of 2 collections.  The question revolved around comparing the contents of the Machine property of

HKLM:\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths

with

$Machine = @(
‘System\CurrentControlSet\Control\ProductOptions’,
‘System\CurrentControlSet\Control\Server Applications’,
‘Software\Microsoft\Windows NT\CurrentVersion’
)

Start by getting the data from the registry

$p = Get-ItemProperty -Path ‘HKLM:\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactpaths’ -Name Machine

$p.Machine
System\CurrentControlSet\Control\ProductOptions
System\CurrentControlSet\Control\Server Applications
Software\Microsoft\Windows NT\CurrentVersion

So the 2 look identical but how do we do that programmatically.

You can’t do

$machine -eq $p.machine

you get nothing back.

You have to use Compare-Object:

Compare-Object $machine $p.machine

You’ll get nothing back so check  everything is equal:

PS> Compare-Object $machine $p.machine -IncludeEqual

InputObject                                                                     SideIndicator
———–                                                                         ————-
System\CurrentControlSet\Control\ProductOptions        ==
System\CurrentControlSet\Control\Server Applications ==
Software\Microsoft\Windows NT\CurrentVersion            ==

Compare-Object returns nothing if the 2 objects match so your comparison ends up as

PS> if ( -not (Compare-Object $machine $p.machine)){‘yay’}else{‘nay’}
yay

You can test it works

$m2 = ‘item1’, ‘item2’, ‘item3’

PS> Compare-Object $machine $m2

InputObject                                          SideIndicator
———–                                          ————-
item1                                                =>
item2                                                =>
item3                                                =>
System\CurrentControlSet\Control\ProductOptions      <=
System\CurrentControlSet\Control\Server Applications <=
Software\Microsoft\Windows NT\CurrentVersion         <=

PS> if ( -not (Compare-Object $machine $m2)){‘yay’}else{‘nay’}
nay


February 29, 2016  6:30 AM

CSV file with [] in headers

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

With the PowerShell Summit registration deadline rapidly approaching I wanted to see how registrations were going. I can down load a CSV file from the event website that lists attendees.

Great. Just need to do some sorting and grouping and I’m golden.

I’m running PowerShell 5.0 on Windows 10 Insider build 14271

First off I discovered that the headers of the CSV file contain [] i.e. they look like this for example:

[UserName]
[REGISTRATIONSTATUS]
[AttendeeType]
[ConfirmationCode]

Sorting by attendee type

Import-Csv -Path C:\test1\AttendeeReport.csv |
Sort-Object -Property [AttendeeType]

works but if I add a check for complete registrations

Import-Csv -Path C:\test1\AttendeeReport.csv |
Where-Object [REGISTRATIONSTATUS] -eq ‘Complete’|
Sort-Object -Property [AttendeeType]

I get nothing back.

Import-Csv -Path C:\test1\AttendeeReport.csv |
Where-Object ‘[REGISTRATIONSTATUS]’ -eq ‘Complete’|
Sort-Object -Property [AttendeeType]

Is no better. You need to revert to old style where-object syntax

Import-Csv -Path C:\test1\AttendeeReport.csv |
Where-Object {$_.'[REGISTRATIONSTATUS]’ -eq ‘Complete’}|
Sort-Object -Property [AttendeeType]

Now I want to group on attendee type

PS> Import-Csv -Path C:\test1\AttendeeReport.csv |
>> Where-Object {$_.'[REGISTRATIONSTATUS]’ -eq ‘Complete’}|
>> Sort-Object -Property [AttendeeType] |
>> Group-Object -Property [AttendeeType] -NoElement
Group-Object : Wildcard characters are not allowed in “[AttendeeType]”.
At line:4 char:1
+ Group-Object -Property [AttendeeType] -NoElement
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Group-Object], NotSupportedException
+ FullyQualifiedErrorId : ExpressionGlobbing2,Microsoft.PowerShell.Commands.GroupObjectCommand

This partially works

Import-Csv -Path C:\test1\AttendeeReport.csv |
Where-Object {$_.'[REGISTRATIONSTATUS]’ -eq ‘Complete’}|
Sort-Object -Property [AttendeeType] |
Group-Object -Property ‘`[AttendeeType`]’ -NoElement

But just gives me a count of the total number of attendees.

I tried a number of ways of dealing with the [] in the headers and therefore in the property names. In the end I decided it was going to be easier to completely reset the headers in the csv file:

Import-Csv -Path C:\test1\AttendeeReport.csv -Header  ‘UserName’, ‘REGISTRATIONSTATUS’, ‘AttendeeType’, ‘ConfirmationCode’, ‘PaymentAuthorization’, ‘RegisteredByEmail’, ‘PromotionCode’, ‘BioName’, ‘BioTitle’, ‘BioEmail’, ‘Created’, ‘Updated’, ‘LastName’, ‘Dietary’, ‘Alumni’, ‘FirstName’, ‘Twitter’, ‘BestEmail’

This means I have to skip the first record because it looks like this:

UserName             : [UserName]
REGISTRATIONSTATUS   : [REGISTRATIONSTATUS]
AttendeeType         : [AttendeeType]
ConfirmationCode     : [ConfirmationCode]
PaymentAuthorization : [PaymentAuthorization]
RegisteredByEmail    : [RegisteredByEmail]
PromotionCode        : [PromotionCode]
BioName              : [BioName]
BioTitle             : [BioTitle]
BioEmail             : [BioEmail]
Created              : [Created]
Updated              : [Updated]
LastName             : [LastName]
Dietary              : [Dietary]
Alumni               : [Alumni]
FirstName            : [FirstName]
Twitter              : [Twitter]
BestEmail            : [BestEmail]

My grouping script is now much simpler

Import-Csv -Path C:\test1\AttendeeReport.csv -Header  ‘UserName’, ‘REGISTRATIONSTATUS’, ‘AttendeeType’, ‘ConfirmationCode’, ‘PaymentAuthorization’, ‘RegisteredByEmail’, ‘PromotionCode’, ‘BioName’, ‘BioTitle’, ‘BioEmail’, ‘Created’, ‘Updated’, ‘LastName’, ‘Dietary’, ‘Alumni’, ‘FirstName’, ‘Twitter’, ‘BestEmail’ |
Select-Object -Skip 1 |
Where-Object REGISTRATIONSTATUS -eq ‘Complete’|
Sort-Object -Property AttendeeType |
Group-Object -Property AttendeeType –NoElement

If I come across other CSV files with [] in the headers I’m going to go for immediate replacement of the headers as the way to get the job done.


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: