(216) Microsoft Intune - Deploy PowerShell Modules
20 hours ago
3 min read
A customer reached out to me inquiring whether is it possible to get PowerShell modules deployed as a win32 app, and of course I said yes it is possible. Currently the customer is deploying WDAC which is getting blocked due to the fact that it is being stored here: C:\Users\*\OneDrive\Documents\PowerShell\Modules which instead they wanted it to be deployed as system based.
The easiest thing I can think of is using a win32 app where the following contains:
# 1. Force TLS 1.2 (Required to communicate with PowerShell Gallery securely)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# 2. Ensure NuGet provider is installed silently without prompts
If (-not (Get-PackageProvider -Name NuGet -ListAvailable -ErrorAction SilentlyContinue)) {
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ForceBootstrap
}
# 3. Ensure PSGallery is registered and set to Trusted safely
If (-not (Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue)) {
Register-PSRepository -Default -InstallationPolicy Trusted
} else {
Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
}
# 4. Install PowerShellGet if not already available
If (-not (Get-Module -Name PowerShellGet -ListAvailable -ErrorAction SilentlyContinue)) {
Install-Module -Name PowerShellGet -Force -AllowClobber -Scope AllUsers
}
# 5. Install Microsoft Graph and Exchange Online Management modules globally for all users
Install-Module -Name Microsoft.Graph -Force -AllowClobber -Scope AllUsers
Install-Module -Name ExchangeOnlineManagement -Force -AllowClobber -Scope AllUsers# Requires Administrator privileges to remove AllUsers modules
# Ensure script runs elevated if needed
If (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Warning "Please run this PowerShell console as an Administrator to successfully remove modules installed for AllUsers."
}
# List of modules to remove
$modulesToRemove = @(
"Microsoft.Graph",
"ExchangeOnlineManagement"
)
foreach ($moduleName in $modulesToRemove) {
Write-Host "Processing module: $moduleName" -ForegroundColor Cyan
# 1. Check if the module is currently loaded in memory and remove it
if (Get-Module -Name $moduleName -ErrorAction SilentlyContinue) {
Write-Host " -> Removing loaded module from session..." -ForegroundColor Yellow
Remove-Module -Name $moduleName -Force -ErrorAction SilentlyContinue
}
# 2. Uninstall all local versions across all scopes (CurrentUser and AllUsers)
$installedModules = Get-Module -Name $moduleName -ListAvailable -ErrorAction SilentlyContinue
if ($installedModules) {
foreach ($mod in $installedModules) {
$version = $mod.Version
$scope = if ($mod.ModuleBase -like "*Program Files*") { "AllUsers" } else { "CurrentUser" }
Write-Host " -> Uninstalling version $version ($scope)..." -ForegroundColor Green
Uninstall-Module -Name $moduleName -RequiredVersion $version -Force -ErrorAction SilentlyContinue
}
} else {
Write-Host " -> $moduleName is not installed." -ForegroundColor DarkGray
}
}
# 3. Optional: Clean up Microsoft.Graph sub-modules (Graph leaves behind dozens of individual service modules like Microsoft.Graph.Authentication, Users, etc.)
Write-Host "Checking for leftover Microsoft.Graph sub-modules..." -ForegroundColor Cyan
$graphSubModules = Get-Module -ListAvailable -ErrorAction SilentlyContinue | Where-Object { $_.Name -like "Microsoft.Graph.*" }
if ($graphSubModules) {
foreach ($subMod in $graphSubModules) {
Write-Host " -> Removing sub-module: $($subMod.Name) (v$($subMod.Version))" -ForegroundColor Yellow
Uninstall-Module -Name $subMod.Name -RequiredVersion $subMod.Version -Force -ErrorAction SilentlyContinue
}
}
Write-Host "Cleanup completed successfully!" -ForegroundColor Green$ModulesPath = "C:\Program Files\WindowsPowerShell\Modules"
$RequiredModules = @("Microsoft.Graph", "ExchangeOnlineManagement")
$MissingModules = @()
foreach ($Module in $RequiredModules) {
$ModuleFolder = Join-Path -Path $ModulesPath -ChildPath $Module
if (Test-Path -Path $ModuleFolder) {
# Check for module manifest at root or within versioned subdirectories
$Manifest = Get-ChildItem -Path $ModuleFolder -Filter "$Module.psd1" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
if (-not $Manifest) {
$MissingModules += $Module
}
} else {
$MissingModules += $Module
}
}
if ($MissingModules.Count -eq 0) {
Write-Output "Detected Microsoft.Graph and ExchangeOnlineManagement modules."
Exit 0
} else {
Write-Output "Missing required module(s): $($MissingModules -join ', ')"
Exit 1
}Once the scripts is packged as a win32 app using system context.

Before it gets installed this will what it will look like.

Once installed, it will install the required modules.

The win32 app will also show succeeded.




Comments