PowerShell Function to Create CimSessions to Remote Computers with Fallback to Dcom
I've found myself writing the same code over and over in my PowerShell scripts where I'm performing a task that requires me to create a CimSession to one or more computers without knowing what version of PowerShell is installed on the remote computers or if PowerShell is even installed on the remote computers.
While it is possible to create a CimSession to a remote computer in any of those scenarios I just described, it's a fair amount of code to add to multiple scripts and then the same redundant code ends up being in multiple files which creates a nightmare if you ever find an issue with the code and need to update it for any reason.
I decided to turn the code I would use to create these CimSessions into a function which is shown below and add it to a script module so I could just call the function from the PowerShell script that needed the CimSessions created before the script performs its task(s).
1#Requires -Version 3.0
2function New-MrCimSession {
3<#
4.SYNOPSIS
5 Creates CimSessions to remote computer(s), automatically determining if the WSMAN
6 or Dcom protocol should be used.
7.DESCRIPTION
8 New-MrCimSession is a function that is designed to create CimSessions to one or more
9 computers, automatically determining if the default WSMAN protocol or the backwards
10 compatible Dcom protocol should be used. PowerShell version 3 is required on the
11 computer that this function is being run on, but PowerShell does not need to be
12 installed at all on the remote computer.
13.PARAMETER ComputerName
14 The name of the remote computer(s). This parameter accepts pipeline input. The local
15 computer is the default.
16.PARAMETER Credential
17 Specifies a user account that has permission to perform this action. The default is
18 the current user.
19.EXAMPLE
20 New-MrCimSession -ComputerName Server01, Server02
21.EXAMPLE
22 New-MrCimSession -ComputerName Server01, Server02 -Credential (Get-Credential)
23.EXAMPLE
24 Get-Content -Path C:\Servers.txt | New-MrCimSession
25.INPUTS
26 String
27.OUTPUTS
28 Microsoft.Management.Infrastructure.CimSession
29.NOTES
30 Author: Mike F Robbins
31 Website: http://mikefrobbins.com
32 Twitter: @mikefrobbins
33#>
34 [CmdletBinding()]
35 param(
36 [Parameter(ValueFromPipeline)]
37 [ValidateNotNullorEmpty()]
38 [string[]]$ComputerName = $env:COMPUTERNAME,
39
40 [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty
41 )
42
43 BEGIN {
44 $Opt = New-CimSessionOption -Protocol Dcom
45
46 $SessionParams = @{
47 ErrorAction = 'Stop'
48 }
49
50 If ($PSBoundParameters['Credential']) {
51 $SessionParams.Credential = $Credential
52 }
53 }
54
55 PROCESS {
56 foreach ($Computer in $ComputerName) {
57 $SessionParams.ComputerName = $Computer
58
59 if ((Test-WSMan -ComputerName $Computer -ErrorAction SilentlyContinue).productversion -match 'Stack: ([3-9]|[1-9][0-9]+)\.[0-9]+') {
60 try {
61 Write-Verbose -Message "Attempting to connect to $Computer using the WSMAN protocol."
62 New-CimSession @SessionParams
63 }
64 catch {
65 Write-Warning -Message "Unable to connect to $Computer using the WSMAN protocol. Verify your credentials and try again."
66 }
67 }
68
69 else {
70 $SessionParams.SessionOption = $Opt
71
72 try {
73 Write-Verbose -Message "Attempting to connect to $Computer using the DCOM protocol."
74 New-CimSession @SessionParams
75 }
76 catch {
77 Write-Warning -Message "Unable to connect to $Computer using the WSMAN or DCOM protocol. Verify $Computer is online and try again."
78 }
79
80 $SessionParams.Remove('SessionOption')
81 }
82 }
83 }
84}
This function will create a CimSession to a remote computer(s) using the WSMAN protocol if the stack version is 3.0 or higher:
The following regular expression matches any version that is 3.0 or higher:
1([3-9]|[1-9][0-9]+)\.[0-9]+
[3-9]
Numbers three through nine.|
or[1-9]
Numbers one through nine.[0-9]
Followed by numbers zero through nine.+
One or more times.\.
A "dot" is a special character so it must be escaped with a backslash.[0-9]+
Numbers zero through nine. One or more times.
I'll use this function to create a CimSession to servers named SQL01 and SQL03:
1New-MrCimSession -ComputerName SQL01, SQL03
Notice in the previous example that one CimSession was created with the WSMAN protocol and the other one with DCOM. Believe it or not, SQL03 is a Windows 2008 Server (non-R2) that does NOT have PowerShell installed at all:
The previously created CimSessions can be used to query information from WMI on the remote computers regardless of which underlying protocol is used for communication:
1Get-CimInstance -CimSession (Get-CimSession) -ClassName Win32_OperatingSystem |
2Select-Object -Property PSComputerName, Caption
Update:
The most recent version can be downloaded from my PowerShell repository on GitHub.
µ