Wednesday, December 02, 2015

PowerShell + SCCM : Run CM cmdlets remotely

Today I saw a tweet about using implicit remoting to load the Configuration Manager on my machine by Justin Mathews. It caught my eye as I have never really tried it, but theoretically it can be done.




Note - The second tweet says "Cannot find a provider with the name CMSite", resolution to which is in the Troubleshooting section at the end.



Use Import-Module


Below is a video showing how you can use Import-Module as mentioned in the tweet, if everything goes without any errors :

video

Below is the code snippet used in the video :


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
# Create the PSSession
$Session = New-PSSession -ComputerName sccm

# Load the CM Module using Implicit Remoting
Import-Module -Name "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" -PSSession $Session

# Check the module is available locally
Get-Module -Name ConfigurationManager

# run the CM cmdlets locally
Get-CMSite

# Oops! We need to set the CMSite as our current location to run the CM cmdlets
Invoke-Command -Session $Session {Set-Location -Path DEX:}

# Run the cmdlet again
Get-CMSite


Use Export-PSSession

Now one can easily be tempted to run the Export-PSSession and store the module locally and next time just import the earlier exported module and start using the CM cmdlets, but it is not that straight forward at-least with the CM cmdlets. 

But there is a way to run the exported cmdlets (or Proxy Functions) by explicitly loading the CM module on the remote session and changing to CMSite provider as the current location ( which I think is pointless as the exported Module should be doing it).

Below is a video showing how to do that :

`

video


Below is the first code snippet (as in above video) used in first PowerShell ISE tab :

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
# Create the PSSession
$Session = New-PSSession -ComputerName sccm

# Load the CM Module in the Remote PSSession and change the current location to your CMSite
Invoke-Command -Session $Session {
                                    Import-Module -Name "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"
                                    Set-Location -path DEX:
                                    }

# Export the Module Locally
Export-PSSession -OutputModule RemoteCMModule -Session $Session -Module ConfigurationManager

# This will work in the current PowerShell session
Import-Module RemoteCMModule

# run the CM cmdlets
Get-CMsite

Now on another ISE Tab, we have to do below :

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023

# check the current PSSessions
Get-PSSession

# On a new PowerShell session , Import the module
Import-Module -Name RemoteCMModule

# try running a CM cmdlet now
Get-CMsite

# check the current PSSessions
$session = Get-PSSession

# One has to explicitly run this
Invoke-Command -Session $Session {
                                    Import-Module -Name "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"
                                    Set-Location -path DEX:
                                    }

# try running a CM cmdlet now
Get-CMsite



Use Invoke-Command

One can always just simply use PowerShell remoting like below :

001
002
003
004
005
006
007
008
009
010
011
012
013

# Create the PSSession
$Session = New-PSSession -ComputerName sccm

# Load the CM Module in the Remote PSSession and change the current location to your CMSite
Invoke-Command -Session $Session {
                                    Import-Module -Name "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"
                                    Set-Location -path DEX:
                                    }

# run the Cmdlets remotely
Invoke-Command -Session $Session {Get-CMSite}



TroubleShooting:

One must remember that even though you are using a PSSession, the ConfigurationManager module should be loaded in the PSSession and your current location should be in the CMSite PSProvider in order to run the CM cmdlets.


You may come across a scenario (similar to mentioned in the tweet) where the CMSite PSProvider might not have loaded correctly when you connected to the PSSession. You can always load the CMSite PSDrive manually , see below video where I deliberately remove the CMSite PSDrive and map it again :
video

Note - Did you notice, I later used ABC as the name of the PSDrive instead of my CMSite DEX ;)

Hope this gives you a better insight on running CM cmdlets remotely. One has to understand that Remoting should be enabled on the CM server where you are connecting.

4 comments:

  1. ConfigMgrDogs showed nice solution for implemmenting remote command, I`ve just created "C:\Users\admin\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1" inside
    ## ADDS A Connect-ConfigMgr ITEM TO THE ISE ADD-ONS MENU ##
    ## Created by Matt Shadbolt - http://blogs.technet.com/b/ConfigMgrDogs ##
    #Create file Microsoft.PowerShellISE_profile.ps1 in doc\windowspowershell

    Function Connect-ConfigMgr {
    Import-Module 'C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'
    Set-Location ELI:\
    }


    $psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Connect-ConfigMgr",
    {
    Connect-ConfigMgr
    },"ALT+F1") | out-Null

    ReplyDelete
    Replies
    1. Nice , Thanks for sharing Alexandr :)

      Delete
  2. We cannot get this up and running. Do you have any idea?
    I have opened the console with the user / the reg keys in HKCU are there but I just cannot connect to the SCCM drive:

    PS C:\Users\username> Invoke-Command -Session $Session {
    >> Import-Module -Name "C:\Program Files (x86)\Microsoft Configuration Manager\Admin
    Console\bin\ConfigurationManager.psd1"
    >> Set-Location -path PR1:
    >> }
    Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
    + CategoryInfo : OpenError: (PR1:PSDriveInfo) [Import-Module], UnauthorizedAccessException
    + FullyQualifiedErrorId : Drive,Microsoft.PowerShell.Commands.ImportModuleCommand
    + PSComputerName : servername

    Cannot find drive. A drive with the name 'PR1' does not exist.
    + CategoryInfo : ObjectNotFound: (PR1:String) [Set-Location], DriveNotFoundException
    + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
    + PSComputerName : servername

    ReplyDelete
    Replies
    1. Do you have access to the .psd1 file placed on the remote CM server ?
      The error says that access is denied. Try doing it interactively on the PSSession opened to the CM server.

      Delete