Simplify Desktop Configuration by Using a Shared PowerShell Module


Summary: Simplify your desktop configuration needs by using a Windows PowerShell module stored on a central file share.


Hey, Scripting Guy! QuestionHey, Scripting Guy! I enjoy using Windows PowerShell modules. I think they are way cool. The thing is, I am not too keen on deploying them to remote workstations. What would be great is if there was a way that I could use a module that was stored on a central server. Is that possible?

— MT


Hey, Scripting Guy! AnswerHello MT, Microsoft Scripting Guy Ed Wilson here. Well, today is a cool day—both literally and figuratively. The weather bit is not unusual, it is January after all, but when the weekend temperatures reached 65 degrees Fahrenheit (18 degrees Celsius) I was hoping that winter was over. The cool (figuratively) part about today is that I am going to speak to the Northern Colorado SharePoint Users Group this evening (via Live Meeting). I have been to Denver several times teaching Windows PowerShell workshops to Microsoft Premier Customers but have not been outside of the city. Tonight I will correct that (at least virtually).

Utilizing a module from a central file share is no different than using a module from one of the two default locations. When a module is placed in the %windir%System32WindowsPowerShellv1.0Modules folder is available to all users. If a module is placed in the %UserProfile%My documentsWindowsPowerShellModules folder it is only available to the specific user. The advantage of placing modules in the %UserProfile% location is the user automatically has permission to perform the installation, whereas system location requires Administrator rights on Windows Vista and later.

Speaking of installation of Windows PowerShell modules, in many cases the installation of a Windows PowerShell module is no more complicated than placing the *.psm1 file in a folder in default user location. The key point is that the folder that is created under the Modules folder must have the same name as the module name itself. When installing modules on a local computer, I use my Copy-Modules.ps1 script.

When I copy a Windows PowerShell module to a network shared location, I follow the same rules. I make sure that the folder that contains the module is the same name as the module name. As an example, I am going to copy my conversion module to a shared drive on one of my Windows Server 2008 R2 Hyperv servers (I am using this shared drive because I already have it shared out on my local network). The module I will use is the same one that I developed during the first Weekend Scripter articles—the ConversionModuleV6 module. As seen here, that module is now shared out (there are also process snapshots stored in XML from a previous Weekend Scripter article).

PS C:> dir \hyperv-boxshared



    Directory: \hyperv-boxshared



Mode                LastWriteTime     Length Name

—-                ————-     —— —-

d—-          1/4/2011   3:53 PM            ConversionModuleV6

-a—        12/13/2010   3:12 PM         32 bios.ps1

-a—        12/13/2010   2:45 PM       1086 Get-SharedFolders.ps1

-a—        12/26/2010   9:24 PM    8344438 Process1_BIGT-PC.xml

-a—          1/4/2011  10:45 AM    9547600 Process1_MRED1.xml

-a—        10/12/2010  11:37 AM    9272696 Process1_TERESA-WIN7.xml

-a—          1/4/2011   4:12 PM    6448040 Process1_WIN7-C1.xml

-a—        12/26/2010   9:26 PM   10451674 Process2_BIGT-PC.xml

-a—          1/4/2011  10:46 AM    9153432 Process2_MRED1.xml

-a—        10/12/2010  11:38 AM   11106128 Process2_TERESA-WIN7.xml

-a—          1/4/2011   4:13 PM    6897914 Process2_WIN7-C1.xml

-a—        12/26/2010   9:27 PM   10283808 Process3_BIGT-PC.xml

-a—          1/4/2011  10:47 AM    9141224 Process3_MRED1.xml

-a—        10/12/2010  11:39 AM   11489310 Process3_TERESA-WIN7.xml

-a—          1/4/2011   4:15 PM    7521712 Process3_WIN7-C1.xml

-a—        12/26/2010   9:29 PM   10163664 Process4_BIGT-PC.xml

-a—          1/4/2011  10:49 AM    9066674 Process4_MRED1.xml

-a—        10/12/2010  11:41 AM   12156950 Process4_TERESA-WIN7.xml

-a—          1/4/2011   4:16 PM    7767062 Process4_WIN7-C1.xml

-a—         7/12/2010  12:06 PM     728046 ScriptingGuysWallPaper.jpg



PS C:>


To import the module from the shared location, I include the path to the module. As seen here, I can even use wildcards for the module name.

Import-Module \hyperv-boxsharedconv*


To see if the module has loaded, I use the Get-Module Windows PowerShell cmdlet. As seen here, the ConversionModuleV6 is the only module currently loaded on my computer and the path confirms that it loaded from the network location.

PS C:> Get-Module | format-list *



ExportedCommands    : {ConvertTo-Feet, ConvertTo-Miles, ConvertTo-MetersPerSecond, C


Name                : ConversionModuleV6

Path                : \hyperv-boxsharedConversionModuleV6ConversionModuleV6.psm1

Description         :

Guid                : 00000000-0000-0000-0000-000000000000

ModuleBase          : \hyperv-boxsharedConversionModuleV6

PrivateData         :

Version             : 0.0

ModuleType          : Script

AccessMode          : ReadWrite

ExportedFunctions   : {[ConvertTo-celsius, ConvertTo-celsius], [ConvertTo-Fahrenheit

                      , ConvertTo-Fahrenheit], [ConvertTo-Feet, ConvertTo-Feet], [Co

                      nvertTo-Kilometers, ConvertTo-Kilometers]…}

ExportedCmdlets     : {}

NestedModules       : {}

RequiredModules     : {}

ExportedVariables   : {}

ExportedAliases     : {[CTCS, CTCS], [CTFH, CTFH], [CTFT, CTFT], [CTKM, CTKM]…}

SessionState        : System.Management.Automation.SessionState

OnRemove            :

ExportedFormatFiles : {}

ExportedTypeFiles   : {}



PS C:>


MT, you need to keep a couple of things in mind. The first thing is that a Windows PowerShell module is basically a script (in our particular application) and that the Script Execution policy must be set so that script execution is permitted. If the script execution policy is set to the default level of restricted an error will be generated (even if the logged on user is an Administrator). Fortunately, the error that is returned informs one of that fact. Even if the execution policy is set to restricted on a particular machine, you can always run a Windows PowerShell script (or module) if you start Windows PowerShell with the bypass option. The command to do this is seen here.

powershell -executionpolicy bypass


One of the really cool uses of a shared module is to permit centralization of Windows PowerShell Profiles for networked users. To do this, the profile on the local computer would simply import the shared module. In this way, I only need to modify one module in one location to permit updates for all the users on the network. I talked about using a module to simplify a Windows PowerShell ISE Profile in the Weekend Scripter: Clean up your PowerShell ISE Profile by using a Module post.


MT, that is all there is to using a module from a centralized file share. Storage of scripts week will continue tomorrow when I will talk about logon scripts.

I invite you to follow me on Twitter or Facebook. If you have any questions, send email to me at or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.


Ed Wilson, Microsoft Scripting Guy 

Comments (2)

  1. MVP Tome Tanasovski wrote a solution and a walkthrough for this Problem.

    See here:

    Corporate Powershell Module Repository…/corporate-powershell-module-repository-part-2-developer-guide

    Andrew Nurse from Microsoft has done a PSGet cmdlets which use NuGetwith PowerShell.

    So take a look at his page:

    NuGet + PowerShell = (also) Crazy Delicious…/nuget-powershell-also-crazy-delicious.html

  2. Anonymous says:

    Another way to run modules from a share is to use the $Env:PSModulePath variable: organize the modules on a network share with each module in a folder matching its name, add the network path (folder containing all the module folders) to the PSModulePath environment variable, and use Import-Module <module name>.  You can also do Get-Module -List and it will show all modules from the network share.

    I've found this method to be very useful in keeping inter-dependent modules portable (i.e. having a development share and a production share) without having to edit paths in script files.  It also helps in scenario of storing scripts/modules in source control (TFS) where multiple people who edit them must have an exclusive workspace for checkout/checkin processes and testing changes.

    For me, when setting up shared modules/scripts, avoiding absolute paths in script code is paramount to keeping maintenance down when the paths change.