|
| 1 | +param ( |
| 2 | + [Parameter()] |
| 3 | + [string] |
| 4 | + $ModuleManifestPath = '{0}\..\src\powershell\ZeroTrustAssessment.psd1' -f (Split-Path -Parent $PSScriptRoot).TrimEnd([io.path]::DirectorySeparatorChar), |
| 5 | + |
| 6 | + [Parameter()] |
| 7 | + [string] |
| 8 | + $OutputPath = '{0}\..\output\RequiredModules' -f (Split-Path -Parent $PSScriptRoot).TrimEnd([io.path]::DirectorySeparatorChar), |
| 9 | + |
| 10 | + [Parameter()] |
| 11 | + [switch] |
| 12 | + $DoNotUpdatePSModulePath, |
| 13 | + |
| 14 | + [Parameter()] |
| 15 | + [switch] |
| 16 | + $SkipModuleInstallation, |
| 17 | + |
| 18 | + [Parameter()] |
| 19 | + [switch] |
| 20 | + $AllowPrerelease |
| 21 | +) |
| 22 | + |
| 23 | +if (-not (Test-Path -Path $OutputPath -PathType Container)) |
| 24 | +{ |
| 25 | + Write-Verbose -Message "Output path not found: $OutputPath" |
| 26 | + $OutputPath = (New-Item -Path $OutputPath -ItemType Directory -Force -ErrorAction Stop).FullName |
| 27 | + Write-Verbose -Message "Created output directory: $OutputPath" |
| 28 | +} |
| 29 | +else |
| 30 | +{ |
| 31 | + $OutputPath = (Get-Item -Path $OutputPath -ErrorAction Stop).FullName |
| 32 | + Write-Verbose -Message "Output path already exists: $OutputPath" |
| 33 | +} |
| 34 | + |
| 35 | +if (-not $DoNotUpdatePSModulePath.IsPresent) |
| 36 | +{ |
| 37 | + Write-Information -MessageData "Updating PSModulePath to include $OutputPath..." |
| 38 | + $modulePath = $env:PSModulePath.Split([System.IO.Path]::PathSeparator).ForEach{$_.TrimEnd([io.path]::DirectorySeparatorChar)} |
| 39 | + if ($OutputPath.TrimEnd([io.path]::DirectorySeparatorChar) -notin $modulePath) |
| 40 | + { |
| 41 | + Write-Verbose -Message "Adding $OutputPath to PSModulePath." |
| 42 | + $env:PSModulePath = (@($OutputPath) + $modulePath) -join [System.IO.Path]::PathSeparator |
| 43 | + Write-Verbose -Message "Updated PSModulePath to:`r`n$env:PSModulePath" |
| 44 | + } |
| 45 | + else |
| 46 | + { |
| 47 | + Write-Information -MessageData "PSModulePath already contains $OutputPath. No update needed." |
| 48 | + } |
| 49 | +} |
| 50 | + |
| 51 | +if (-not $SkipModuleInstallation.IsPresent) |
| 52 | +{ |
| 53 | + Write-Verbose -Message "Installing required modules to $OutputPath..." |
| 54 | + $moduleManifest = Import-PowerShellDataFile -Path $ModuleManifestPath -ErrorAction Stop |
| 55 | + [Microsoft.PowerShell.Commands.ModuleSpecification[]]$requiredModules = $moduleManifest.RequiredModules |
| 56 | + [Microsoft.PowerShell.Commands.ModuleSpecification[]]$externalModuleDependencies = $moduleManifest.PrivateData.ExternalModuleDependencies |
| 57 | + # [Microsoft.PowerShell.Commands.ModuleSpecification[]]$windowsPowerShellRequiredModules = $moduleManifest.PrivateData.WindowsPowerShellRequiredModules |
| 58 | + |
| 59 | + $requiredModuleToSave = $requiredModules.Where{$_.Name -notin $externalModuleDependencies.Name} |
| 60 | + # $requiredModuleToSave += $windowsPowerShellRequiredModules.Where{ $_.Name -notin $requiredModules.Name -and $_.Name -notin $externalModuleDependencies.Name } |
| 61 | + |
| 62 | + if (-not $SkipModuleInstallation.IsPresent) |
| 63 | + { |
| 64 | + Write-Host -Object "`r`n" |
| 65 | + Write-Host -Object 'Resolving dependencies...' -ForegroundColor Green |
| 66 | + |
| 67 | + $saveModuleCmdParams = @{ |
| 68 | + Path = $OutputPath |
| 69 | + } |
| 70 | + |
| 71 | + if ($saveModuleCmd = (Get-Command -Name Save-PSResource -ErrorAction Ignore)) |
| 72 | + { |
| 73 | + $saveModuleCmdParams.Add('TrustRepository', $true) |
| 74 | + $saveModuleCmdParams.Add('Prerelease', $AllowPrerelease.IsPresent) |
| 75 | + Write-Verbose -Message "Saving required modules using Save-PSResource..." |
| 76 | + } |
| 77 | + elseif ($saveModuleCmd = (Get-Command -Name Save-Module -ErrorAction Ignore)) |
| 78 | + { |
| 79 | + $saveModuleCmdParams.Add('Force', $true) |
| 80 | + $saveModuleCmdParams.Add('AllowPrerelease', $AllowPrerelease.IsPresent) |
| 81 | + Write-Verbose -Message "Saving required modules using Save-Module..." |
| 82 | + } |
| 83 | + else |
| 84 | + { |
| 85 | + Write-Error -Message 'Neither Save-PSResource nor Save-Module is available. Please install the PowerShellGet module to save required modules.' |
| 86 | + return |
| 87 | + } |
| 88 | + |
| 89 | + foreach ($moduleSpec in $requiredModuleToSave) |
| 90 | + { |
| 91 | + Write-Verbose -Message ("Saving module {0} with version {1}..." -f $moduleSpec.Name, $moduleSpec.Version) |
| 92 | + $saveModuleCmdParamsClone = $saveModuleCmdParams.Clone() |
| 93 | + $isModulePresent = Get-Module -Name $moduleSpec.Name -ListAvailable -ErrorAction Ignore | Where-Object { |
| 94 | + $isValid = $true |
| 95 | + if ($moduleSpec.Guid) |
| 96 | + { |
| 97 | + $isValid = $_.Guid -eq $moduleSpec.Guid |
| 98 | + } |
| 99 | + |
| 100 | + if ($moduleSpec.Version) |
| 101 | + { |
| 102 | + $isValid = $isValid -and $_.Version -ge [Version]$moduleSpec.Version |
| 103 | + } |
| 104 | + elseif ($moduleSpec.RequiredVersion) |
| 105 | + { |
| 106 | + $isValid = $isValid -and $_.Version -eq [Version]$moduleSpec.RequiredVersion |
| 107 | + } |
| 108 | + |
| 109 | + $isValid |
| 110 | + } |
| 111 | + |
| 112 | + if ($isModulePresent) |
| 113 | + { |
| 114 | + Write-Host -Object (' ✅ Module {0} found (v{1}).' -f $moduleSpec.Name,$isModulePresent[0].Version) -ForegroundColor Green |
| 115 | + continue |
| 116 | + } |
| 117 | + |
| 118 | + try |
| 119 | + { |
| 120 | + $saveModuleCmdParamsClone['Name'] = $moduleSpec.Name |
| 121 | + if ($moduleSpec.Version -and $saveModuleCmd.Name -eq 'Save-Module') |
| 122 | + { |
| 123 | + $saveModuleCmdParamsClone['MinimumVersion'] = $moduleSpec.Version |
| 124 | + } |
| 125 | + elseif ($moduleSpec.Version -and $saveModuleCmd.Name -eq 'Save-PSResource') |
| 126 | + { |
| 127 | + $saveModuleCmdParamsClone['Version'] = '[{0}, ]' -f $moduleSpec.Version |
| 128 | + } |
| 129 | + |
| 130 | + & $saveModuleCmd @saveModuleCmdParamsClone |
| 131 | + Write-Host -Object (' ⬇️ Module {0} saved successfully.' -f $moduleSpec.Name) -ForegroundColor Green |
| 132 | + } |
| 133 | + catch |
| 134 | + { |
| 135 | + Write-Host -Object (' ❌ Failed to save module {0}: {1}' -f $moduleSpec.Name, $_) -ForegroundColor Red |
| 136 | + } |
| 137 | + } |
| 138 | + } |
| 139 | + |
| 140 | +} |
| 141 | +else |
| 142 | +{ |
| 143 | + Write-Verbose -Message "Skipping module installation as per parameter. Required modules will not be saved to $OutputPath." |
| 144 | + return |
| 145 | +} |
0 commit comments