I love that PSU gives me the ability to install modules from the gallery, but something I’ve noticed is that the modules you install are saved under the Repository folder, which means they are pushed to GitHub in their entirety.
For small modules, that’s fine, but I’m eyeballing the Microsoft.Graph modules, and they’re relatively big. Like 20-50MB per module.
I’m on an Azure App Service so I guess it’s non-trivial to install a module “globally” outside of PSU (@adam you might be able to comment on that).
It’s a bit of a conundrum. I love that the GitHub sync means I can restore PSU from scratch if necessary, but I’m not in love with the idea of saving large binary modules to a GitHub repo.
Anybody got any thoughts on this? Maybe there’s something I can add to the startup script to check that certain modules are installed (outside of the Repository folder) and install them if they’re missing?
OK, I tried calling Save-Module from a test script to make sure it works, and I got this error:
[error] NuGet provider is required to interact with NuGet-based repositories. Please ensure that ‘2.8.5.201’ or newer version of NuGet provider is installed.
So even though I can install modules from the UI, I can’t from a script. Might need some help with that one!
OK the Save-PSResource function is good to know! Thanks Adam.
The reason I’m not thinking about .gitignore is that I like the idea that the module requirement is persisted to GitHub. I want to be confident that a fresh install of PSU will “know” which modules it needs to install. Plus of course I have hand-made modules in the repository that I definitely do want synced to GitHub.
I’ll do some experimenting with my “install modules somewhere outside of the repository on server start” idea and see if it holds water.
Hmm. Hit a bit of a snag here with Save-PSResource. It’s throwing a weird error about an “Index” parameter. I’m just passing it a name and a path, so I’m not sure if I’m doing something wrong.
Here’s my script:
$modules = @(
'Microsoft.Graph.Users'
# etc
)
# make a 'Modules' folder alongside the repository and add it to the path
$path = Join-Path $Repository "..\Modules\"
if (-not (Test-Path $path)) {
New-Item -Path $path -ItemType Directory -Force
}
$path = Resolve-Path $path
# $env:PSModulePath += ";$path"
$path
$modules | Foreach-Object {
# if (Get-PSResource $_) {
# return;
# }
"Saving module '$_'"
Save-PSResource -Name $_ -Path $path
}
… and here’s the output:
[error] Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
Path
----
D:\home\data\PowershellUniversal\Modules\
Saving module 'Microsoft.Graph.Users'
(it looks like the error’s happening before the output, but that’s just a nuance of the way PowerShell/PSU displays the results of the script. The error definitely happens on the Save-PSResource line.)
Ah! I had to add -TrustRepository to the call. I think there’s a bug (at least in the version that’s bundled with PSU) in the code to prompt the user to trust the repository. Probably in their String.Format call.
Welcome To Microsoft Graph!
Id DisplayName Mail
-- ----------- ----
<my guid> Matt Hamilton mhamilton@wodongatafe.edu.au
So I will be trying to move all the “big” third party modules to a place outside of the repository now, and configuring PSU to ensure they’re installed when the server starts. Exciting!
I’ve updated this section of my On-Startup.ps1 script slightly so it uninstalls the required modules if there’s a new version available. Just in case anyone’s using it!
$modules = @(
'TOPdeskPS'
'Microsoft.Graph.Authentication'
'Microsoft.Graph.Users'
'Microsoft.Graph.Users.Actions'
'Microsoft.Graph.Groups'
'Microsoft.Graph.Teams'
'Microsoft.Graph.Identity.DirectoryManagement'
'Microsoft.Graph.Identity.SignIns'
'Microsoft.Graph.DeviceManagement'
'Microsoft.Graph.DeviceManagement.Enrolment'
'Microsoft.Graph.DeviceManagement.Actions'
'Microsoft.Graph.Security'
# etc
)
# make a 'Modules' folder alongside the repository
$path = Join-Path $Repository '..\Modules\'
if (-not (Test-Path $path)) {
New-Item -Path $path -ItemType Directory -Force
}
$path = Resolve-Path $path
# Add it to the path
if ($env:PSModulePath -split ';' -notcontains $path) {
$env:PSModulePath += ";$path"
}
# Save the modules to our new folder
$modules | Foreach-Object {
$installed = Get-PSResource -Name $_ -Path $path
if ($installed) {
Write-Host "Checking for updates for '$_'"
$mod = Find-PSResource -Name $_
if ($mod.Version -le $installed.Version) {
Write-Host "Skipping '$_'"
return;
}
Write-Host "Uninstalling '$_' so we upgrade to version $($mod.Version)"
Uninstall-PSResource -Name $_
}
Write-Host "Installing '$_'"
Save-PSResource -Name $_ -Path $path -TrustRepository -IncludeXML
}