Watch out when using $PSModuleAutoLoadingPreference = “none” in a PS Remote Session in Windows Server 2016

Recently I discovered a change in the default behavior of PSRemoting Sessions in Windows Server 2012 R2 vs. Server 2016.

I was migrating a script from 2012R2 to 2016 and surprisingly, I got this error:

 

The term ‘Get-Date’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included

, verify that the path is correct and try again.

+ CategoryInfo : ObjectNotFound: (Get-Date:String) [], CommandNotFoundException

+ FullyQualifiedErrorId : CommandNotFoundException

+ PSComputerName : ctaa01

 

When I vestigated the issue I found that I was using PSModuleAutoLoadingPrefernce = “none” in invoke-command!

Consider this:

$requestBody = Get-Content $req -Raw | ConvertFrom-Json
Invoke-Command -ComputerName localhost -ScriptBlock {
    $PSModuleAutoLoadingPreference = "none"
    Get-Date
}

This works against a 2012R2 but not against a 2016, so aparantly the default utility PS module is not available on 2016 when connecting via remote.

Usually I will get auto imported, but not this time as my script was disabling auto loading of modules as the first line in the remote command!

So what to do?

We have 2 ways to fix this

1. make sure you dont disable autoloading of modules:

$requestBody = Get-Content $req -Raw | ConvertFrom-Json
Invoke-Command -ComputerName localhost -ScriptBlock {
    Get-Date
}

the downside of this solution is that some times you really want to disabled it (such as when working with a machine that has both SMLets and the official Server Manager modules, or other module that can collide)

2. Load the utility module explicitly

$requestBody = Get-Content $req -Raw | ConvertFrom-Json
Invoke-Command -ComputerName localhost -ScriptBlock {
    $PSModuleAutoLoadingPreference = "none"
    Import-Module Microsoft.PowerShell.Utility
    Get-Date
}

That all for now! Happy shelling!


Leave a Reply