ModulePathUnifier.psm1
function Test-IsEnabled { <# .SYNOPSIS Returns, whether the module should act. .DESCRIPTION Returns, whether the module should act. Should NOT act if: - Is Disabled - Is not on Windows - Is a SYSTEM account .EXAMPLE PS C:\> Test-IsEnabled Returns, whether the module should act. #> [OutputType([bool])] [CmdletBinding()] param () process { $isWin = $PSVersionTable.PSVersion.Major -lt 6 -or $IsWindows if (-not $isWin) { return $false } if ($env:LOCALAPPDATA) { $disablePath = Join-Path $env:LOCALAPPDATA "ModulePathUnifier_Disabled.txt" if (Test-Path $disablePath) { return $false } } [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value -notmatch '^S-1-5-' } } function Update-ModulePath { <# .SYNOPSIS Creates a central module path and updates the profile to load it. .DESCRIPTION Creates a central module path and updates the profile to load it. .EXAMPLE PS C:\> Update-ModulePath Creates a central module path and updates the profile to load it. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param () process { if (-not (Test-IsEnabled)) { return } if (-not (Test-Path $script:modulePath)) { $null = New-Item -Path $script:modulePath -ItemType Directory -Force } $insertLine = 'if ($env:PSModulePath -notlike ''*{0}*'') {{ $env:PSModulePath = ''{0}'', $env:PSModulePath -join '';'' }}' -f $script:modulePath if ($env:PSModulePath -notlike "*$script:modulePath*") { $env:PSModulePath = $script:modulePath, $env:PSModulePath -join ';' } $path = $profile.CurrentUserAllHosts $profileFolder = Split-Path $Path if (-not (Test-Path $profileFolder)) { $null = New-Item -Path $profileFolder -ItemType Directory -Force } if (-not (Test-Path $path)) { $insertLine | Set-Content -Path $path return } if ((Get-Content -Path $Path) -contains $insertLine) { return } $profileContent = @($insertLine) + @(Get-Content -Path $path) $profileContent | Set-Content -Path $path } } function Copy-MpuModule { <# .SYNOPSIS Copies the calling command into the shared modulepath. .DESCRIPTION Copies the calling command into the shared modulepath. Call this during your module's import to make it available to all PowerShell versions. .EXAMPLE PS C:\> Copy-MpuModule Copies the calling command into the shared modulepath. #> [CmdletBinding()] param ( ) process { if (-not (Test-IsEnabled)) { return } $caller = (Get-PSCallStack)[1] $module = $caller.InvocationInfo.MyCommand.Module if (-not $module -and $caller.InvocationInfo.MyCommand.Name -like '*.psm1') { $module = Get-Module -Name ($caller.InvocationInfo.MyCommand.Path -replace 'psm1$', 'psd1') -ListAvailable -ErrorAction Ignore # Case: Module not found if (-not $module -or $module.Guid -eq [guid]::Empty) { return } } $moduleBase = $module.ModuleBase if (-not $moduleBase) { return } if ($moduleBase -like "$env:ProgramFiles*") { return } $targetRoot = Join-Path -Path $script:modulePath -ChildPath "$($module.Name)\$($module.Version)" if (Test-Path -Path "$targetRoot\$($module.Name).psd1") { return } if (-not (Test-Path -Path $targetRoot)) { $null = New-Item -Path $targetRoot -ItemType Directory -Force } Copy-Item -Path "$moduleBase\*" -Destination $targetRoot -Recurse } } function Disable-ModulePathUnifier { <# .SYNOPSIS Disables the ModulePathUnifier module. .DESCRIPTION Disables the ModulePathUnifier module. Sets a flag in the user profile (under LocalAppData) that tells this module to stop doing its work. Use Enable-ModulePathUnifier to reenable it. .EXAMPLE PS C:\> Disable-ModulePathUnifier Disables the ModulePathUnifier module. #> [CmdletBinding()] param ( ) process { if (-not $env:LOCALAPPDATA) { return } $disablePath = Join-Path $env:LOCALAPPDATA "ModulePathUnifier_Disabled.txt" 'Module has been disabled and will not copy modules or maintain a central modulepath anymore. Does not affect your $profile content' | Set-Content $disablePath } } function Enable-ModulePathUnifier { <# .SYNOPSIS Re-enables this module after having previously disabled it. .DESCRIPTION Re-enables this module after having previously disabled it. Use Disable-ModulePathUnifier to disable this module. .EXAMPLE PS C:\> Enable-ModulePathUnifier Re-enables this module after having previously disabled it. #> [CmdletBinding()] param ( ) process { if (-not $env:LOCALAPPDATA) { return } $disablePath = Join-Path $env:LOCALAPPDATA "ModulePathUnifier_Disabled.txt" Remove-Item -Path $disablePath -ErrorAction Ignore $script:modulePath = ([System.Environment]::GetFolderPath('MyDocuments')),'PSModules' -join '\' } } if (Test-IsEnabled) { $script:modulePath = ([System.Environment]::GetFolderPath('MyDocuments')),'PSModules' -join '\' Update-ModulePath } |