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 :


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 :

`



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 :

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.

6 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
    2. I'm encountering this exact same error. The commands work when run on the CM Server as the user account being used, but I cannot get this to run remotely. Did you ever find a solution for this?

      Delete
    3. Hi Jonathan,

      Can you check if you have access to read the .psd1 file on the remote server?

      Delete