[Powershell] Missing shared custom modules when using Powershell Remoting

In my previous post: Centralize Powershell Script (Modules) Repository, it describes on how to create a custom module and load it on any server. And like the title of this post indicated when you try to connect to a remote server using Powershell remoting, you’ll notice that the custom module is missing ( More information about Powershell Remoting ). This is  because it’s doing a double-hop, First hop is to connect to server (using Enter-PSSession or New-PSSession), next hop is to access the shared folder containing the custom module.

To solve this issue we need to Enable the Credential Service Security Provider (CredSSP) both on remote and host server.

#1 On the server wherein the powershell console instance is started you need to enable the client role.

#2 On the server wherein you want to connect remotely you need to enable server role.

#3 On the server wherein the powershell script is hosted you also need to enable the server role.

Run the following scripts (Run as Administrator):

Script for # 1:
Enable-WSManCredSSP -role Client -DelegateComputer  -force
Script for # 2:
Enable-WSManCredSSP -role Server -force
Script for # 3:
Enable-WSManCredSSP -role Server -force

Powershell remoting with CredSSP:

To connect either by Enter-PSSession or New-PSSession you need to supply extra argument:

$session = New-PSSession -ComputerName  -Authentication CredSSP -Credential Get-Credential

Since i used Get-Credential it would prompt for credential:

Update:

If it still doesn’t work, try restarting the Windows Remote Management (WS-Management) service.

In Run Type, services.msc

In the Name look for: Windows Remote Management (WS-Management), right click Restart.

[Powershell] Centralize Powershell Script (Modules) Repository

In this post I will try to describe on how you can centralize your powershell scripts (custom modules) so that it can be  loaded from any servers in the system.

Note: The sample below is using Powershell v2.0 and is intended for Windows Server 2008 and up.

Centralize Powershell Repository Diagram:

Centralize Powershell Scripting Diagram

In this diagram it states that there are 3 custom modules on the powershell scripting server that can be loaded from any of the servers in the network.

Powershell Server Setup Steps:

Necessary steps needs to be undertaken to the Powershell Server is as follows:

1. Create a shared folder in the PS Server that will contain all the custom modules. Assign appropriate permissions.

2. Create/move custom modules in the shared folder. On instructions on how to create a custom module, click here.

Quick Guide: Creating Custom Powershell Module

Creating a custom script module is quite easy, you just need to create a psd1 file (contains manifest information) and psm1 file (basically contains the dot sourcing of all scripts you want to load in the module) and place it in a folder with name equal to the module name.

Sample Folder structure: The C:\Modules will be setup as shared folder.

Contents of Sample.psd1 file

#
# Module manifest for module 'Sample'
#
# Generated by: Randy Aldrich Paulo
#
# Generated on:
#

@{

# Script module or binary module file associated with this manifest
ModuleToProcess = 'Sample.psm1'

# Version number of this module.
ModuleVersion = '1.0'

# ID used to uniquely identify this module
GUID = 'c78688f252-fc04-413a-8b0e-5cfc7e78dcd6'

# Author of this module
Author = 'Randy Aldrich Paulo'

# Company or vendor of this module
CompanyName = 'My Company'

# Copyright statement for this module
Copyright = '(c) 2012 Randy Paulo.'

# Description of the functionality provided by this module
Description = 'Description'

# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = ''

# Name of the Windows PowerShell host required by this module
PowerShellHostName = ''

# Minimum version of the Windows PowerShell host required by this module
PowerShellHostVersion = ''

# Minimum version of the .NET Framework required by this module
DotNetFrameworkVersion = ''

# Minimum version of the common language runtime (CLR) required by this module
CLRVersion = ''

# Processor architecture (None, X86, Amd64, IA64) required by this module
ProcessorArchitecture = ''

# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @()

# Assemblies that must be loaded prior to importing this module
RequiredAssemblies = @()

# Script files (.ps1) that are run in the caller's environment prior to importing this module
ScriptsToProcess = @()

# Type files (.ps1xml) to be loaded when importing this module
TypesToProcess = @()

# Format files (.ps1xml) to be loaded when importing this module
FormatsToProcess = @()

# Modules to import as nested modules of the module specified in ModuleToProcess
NestedModules = @()

# Functions to export from this module
FunctionsToExport = '*'

# Cmdlets to export from this module
CmdletsToExport = '*'

# Variables to export from this module
VariablesToExport = '*'

# Aliases to export from this module
AliasesToExport = '*'

# List of all modules packaged with this module
ModuleList = @()

# List of all files packaged with this module
FileList = 'DataMgtDeployment.psm1'

# Private data to pass to the module specified in ModuleToProcess
PrivateData = ''

}

Contents of Sample.psm1 file

#
# DataMgtDeployment Module
#

$ModulePath = \\PowershellServer\Modules\Sample
# Set the location
Set-Location $ModulePath

# Reference the Scripts
. .MyFunction.ps1
. .MyFunction2.ps1

3. Update System Variable PSModulePath to include the location of custom modules

Right Click Computer -> Propeties -> Advanced Settings -> Environment Variables -> Add a semi-colon (;) at the end and add the path of the custom module (Ex. C:\Modules)

4.  To test whether the setup is correct, run the Powershell Command Prompt (As Administrator) and type:


Get-Module -ListAvailable

It should display your custom module.

 

Server(s) Setup Steps:

After the module is properly setup you can now load it on any servers on the network once the following setup steps have been performed:

1. Update System Variable PSModulePath to include the location of custom modules (shared folder)

Right Click Computer -> Propeties -> Advanced Settings -> Environment Variables -> Add a semi-colon (;) at the end and add the path of the custom module (Ex. \\PowershellServer\Modules)

2. Since we are loading the module from a shared location we need to change the execution policy to RemoteSigned. For information about execution-policy see: About Execution Policy. Execute the following script (as Administrator):


Set-ExecutionPolicy RemotedSigned -force

3. After step 2, when you try to load the custom module it will still throw an exception, to solve the problem we need to add the path of shared folder to the list of trusted sites.

Open Internet Explorer -> Tools -> Internet Options -> Go to Security Tab

Click Trusted Sites -> Sites -> In the add type: file://PowershellServer (replace it with actual servername)

Click Add -> Close -> Ok.

Now you can load the custom module from remote powershell server into any of the servers in the network (as long as you did the Server(s) Setup Steps.

Using the shared custom module in powershell remoting is possible but you need to update some settings see my next blog: [Powershell] Missing shared custom modules when using Powershell Remoting