diff --git a/images/win/Windows2016-Azure.json b/images/win/Windows2016-Azure.json
index a75a946d3..d87970a7f 100644
--- a/images/win/Windows2016-Azure.json
+++ b/images/win/Windows2016-Azure.json
@@ -117,9 +117,12 @@
{
"type": "powershell",
"environment_vars": [
- "ImageVersion={{user `image_version`}}"
+ "ImageVersion={{user `image_version`}}",
+ "TOOLSET_JSON_PATH={{user `toolset_json_path`}}",
+ "PSMODULES_ROOT_FOLDER={{user `psmodules_root_folder`}}"
],
"scripts":[
+ "{{ template_dir }}/scripts/Installers/Install-PowerShellModules.ps1",
"{{ template_dir }}/scripts/Installers/Windows2016/Initialize-VM.ps1"
],
"execution_policy": "unrestricted"
@@ -716,6 +719,9 @@
"type": "powershell",
"inline": [
"pwsh -File '{{user `image_folder`}}\\SoftwareReport\\SoftwareReport.Generator.ps1'"
+ ],
+ "environment_vars":[
+ "TOOLSET_JSON_PATH={{user `toolset_json_path`}}"
]
},
{
diff --git a/images/win/Windows2019-Azure.json b/images/win/Windows2019-Azure.json
index 38639f01a..4c3c09e32 100644
--- a/images/win/Windows2019-Azure.json
+++ b/images/win/Windows2019-Azure.json
@@ -117,9 +117,12 @@
{
"type": "powershell",
"environment_vars": [
- "ImageVersion={{user `image_version`}}"
+ "ImageVersion={{user `image_version`}}",
+ "TOOLSET_JSON_PATH={{user `toolset_json_path`}}",
+ "PSMODULES_ROOT_FOLDER={{user `psmodules_root_folder`}}"
],
"scripts":[
+ "{{ template_dir }}/scripts/Installers/Install-PowerShellModules.ps1",
"{{ template_dir }}/scripts/Installers/Windows2019/Initialize-VM.ps1"
],
"execution_policy": "unrestricted"
@@ -715,6 +718,9 @@
"type": "powershell",
"inline": [
"pwsh -File '{{user `image_folder`}}\\SoftwareReport\\SoftwareReport.Generator.ps1'"
+ ],
+ "environment_vars":[
+ "TOOLSET_JSON_PATH={{user `toolset_json_path`}}"
]
},
{
diff --git a/images/win/scripts/Installers/Install-AzureModules.ps1 b/images/win/scripts/Installers/Install-AzureModules.ps1
index 8d3a4fe56..d03100bd3 100644
--- a/images/win/scripts/Installers/Install-AzureModules.ps1
+++ b/images/win/scripts/Installers/Install-AzureModules.ps1
@@ -5,8 +5,6 @@
$ErrorActionPreference = "Stop"
-Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
-
# The correct Modules need to be saved in C:\Modules
$installPSModulePath = $env:PSMODULES_ROOT_FOLDER
if (-not (Test-Path -LiteralPath $installPSModulePath))
diff --git a/images/win/scripts/Installers/Install-Docker.ps1 b/images/win/scripts/Installers/Install-Docker.ps1
index 00e665172..433d76da4 100644
--- a/images/win/scripts/Installers/Install-Docker.ps1
+++ b/images/win/scripts/Installers/Install-Docker.ps1
@@ -5,10 +5,6 @@
## can continue.
################################################################################
-Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
-Write-Host "Install-Module DockerProvider"
-Install-Module DockerMsftProvider -Force
-
Write-Host "Install-Package Docker"
Install-Package -Name docker -ProviderName DockerMsftProvider -Force
Start-Service docker
diff --git a/images/win/scripts/Installers/Install-PowerShellModules.ps1 b/images/win/scripts/Installers/Install-PowerShellModules.ps1
new file mode 100644
index 000000000..f6cb22d03
--- /dev/null
+++ b/images/win/scripts/Installers/Install-PowerShellModules.ps1
@@ -0,0 +1,34 @@
+$ErrorActionPreference = "Stop"
+
+# Set TLS1.2
+[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor "Tls12"
+
+Write-Host "Setup PowerShellGet"
+Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
+
+# Specifies the installation policy
+Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
+
+# Install PowerShell modules
+$modules = (Get-ToolsetContent).powershellModules
+
+foreach($module in $modules)
+{
+ $moduleName = $module.name
+ Write-Host "Installing ${moduleName} module"
+
+ if ($module.versions)
+ {
+ foreach ($version in $module.versions)
+ {
+ Write-Host " - $version"
+ Install-Module -Name $moduleName -RequiredVersion $version -Scope AllUsers -SkipPublisherCheck -Force
+ }
+ continue
+ }
+
+ Install-Module -Name $moduleName -Scope AllUsers -SkipPublisherCheck -Force
+}
+
+Import-Module Pester
+Invoke-PesterTests -TestFile "PowerShellModules" -TestName "PowerShellModules"
\ No newline at end of file
diff --git a/images/win/scripts/Installers/Install-SQLPowerShellTools.ps1 b/images/win/scripts/Installers/Install-SQLPowerShellTools.ps1
index 8369a9944..7c0a3cfd1 100644
--- a/images/win/scripts/Installers/Install-SQLPowerShellTools.ps1
+++ b/images/win/scripts/Installers/Install-SQLPowerShellTools.ps1
@@ -19,7 +19,3 @@ Install-Binary -Url $SharedManagementObjectsUrl -Name $SharedManagementObjectsNa
$PowerShellToolsName = "PowerShellTools.msi"
$PowerShellToolsUrl = "${BaseUrl}/${PowerShellToolsName}"
Install-Binary -Url $PowerShellToolsUrl -Name $PowerShellToolsName
-
-# install sqlserver PS module
-Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
-Install-Module -Name SqlServer -AllowClobber
\ No newline at end of file
diff --git a/images/win/scripts/Installers/Install-WindowsUpdates.ps1 b/images/win/scripts/Installers/Install-WindowsUpdates.ps1
index a57594d9d..eb19a3ea0 100644
--- a/images/win/scripts/Installers/Install-WindowsUpdates.ps1
+++ b/images/win/scripts/Installers/Install-WindowsUpdates.ps1
@@ -5,5 +5,4 @@
################################################################################
Write-Host "Run windows updates"
-Install-Module -Name PSWindowsUpdate -Force -AllowClobber
Get-WUInstall -MicrosoftUpdate -AcceptAll -Install -IgnoreUserInput -IgnoreReboot
diff --git a/images/win/scripts/Installers/Windows2016/Initialize-VM.ps1 b/images/win/scripts/Installers/Windows2016/Initialize-VM.ps1
index 5afc6e61f..81b2ae1b6 100644
--- a/images/win/scripts/Installers/Windows2016/Initialize-VM.ps1
+++ b/images/win/scripts/Installers/Windows2016/Initialize-VM.ps1
@@ -33,17 +33,6 @@ function Disable-UserAccessControl {
# Set TLS1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor "Tls12"
-Import-Module -Name ImageHelpers -Force
-
-Write-Host "Setup PowerShellGet"
-# Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
-Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
-Install-Module -Name PowerShellGet -Force
-Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
-
-Write-Host "Install the latest Pester version"
-Install-Module Pester -Scope AllUsers -SkipPublisherCheck -Force
-
Write-Host "Disable Antivirus"
Set-MpPreference -DisableRealtimeMonitoring $true
diff --git a/images/win/scripts/Installers/Windows2019/Initialize-VM.ps1 b/images/win/scripts/Installers/Windows2019/Initialize-VM.ps1
index e57ccb981..376349866 100644
--- a/images/win/scripts/Installers/Windows2019/Initialize-VM.ps1
+++ b/images/win/scripts/Installers/Windows2019/Initialize-VM.ps1
@@ -30,17 +30,6 @@ function Disable-UserAccessControl {
Write-Host "User Access Control (UAC) has been disabled."
}
-Import-Module -Name ImageHelpers -Force
-
-Write-Host "Setup PowerShellGet"
-# Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
-Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
-Install-Module -Name PowerShellGet -Force
-Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
-
-Write-Host "Install the latest Pester version"
-Install-Module Pester -Scope AllUsers -SkipPublisherCheck -Force
-
Write-Host "Disable Antivirus"
Set-MpPreference -DisableRealtimeMonitoring $true
diff --git a/images/win/scripts/SoftwareReport/SoftwareReport.Common.psm1 b/images/win/scripts/SoftwareReport/SoftwareReport.Common.psm1
index 2ca0b8e01..965b5fb93 100644
--- a/images/win/scripts/SoftwareReport/SoftwareReport.Common.psm1
+++ b/images/win/scripts/SoftwareReport/SoftwareReport.Common.psm1
@@ -243,6 +243,21 @@ function Get-PowerShellAzureModules {
}
}
+function Get-PowerShellModules {
+ $modules = (Get-ToolsetContent).powershellModules.name
+
+ $psModules = Get-Module -Name $modules -ListAvailable | Sort-Object Name | Group-Object Name
+ $psModules | ForEach-Object {
+ $moduleName = $_.Name
+ $moduleVersions = ($_.group.Version | Sort-Object -Unique) -join '
'
+
+ [PSCustomObject]@{
+ Module = $moduleName
+ Version = $moduleVersions
+ }
+ }
+}
+
function Get-CachedDockerImages {
return (docker images --digests --format "* {{.Repository}}:{{.Tag}}").Split("*") | Where-Object { $_ }
}
diff --git a/images/win/scripts/SoftwareReport/SoftwareReport.Generator.ps1 b/images/win/scripts/SoftwareReport/SoftwareReport.Generator.ps1
index b0de49a54..d4657c1c4 100644
--- a/images/win/scripts/SoftwareReport/SoftwareReport.Generator.ps1
+++ b/images/win/scripts/SoftwareReport/SoftwareReport.Generator.ps1
@@ -1,6 +1,3 @@
-# Install MarkdownPS module for software report generation
-Install-Module MarkdownPS -Force -Scope AllUsers
-
Import-Module MarkdownPS
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Android.psm1") -DisableNameChecking
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Browsers.psm1") -DisableNameChecking
@@ -41,7 +38,6 @@ $markdown += New-MDList -Style Unordered -Lines @(
(Get-PHPVersion),
(Get-JuliaVersion),
(Get-PerlVersion),
- (Get-PowershellCoreVersion),
(Get-NodeVersion)
)
@@ -190,7 +186,11 @@ $markdown += "``Location $($frameworks.Path)``"
$markdown += New-MDNewLine
$markdown += New-MDList -Lines $frameworks.Versions -Style Unordered
-$markdown += New-MDHeader "Azure Powershell Modules" -Level 3
+# PowerShell Tools
+$markdown += New-MDHeader "PowerShell Tools" -Level 3
+$markdown += New-MDList -Lines (Get-PowershellCoreVersion) -Style Unordered
+
+$markdown += New-MDHeader "Azure Powershell Modules" -Level 4
$markdown += Get-PowerShellAzureModules | New-MDTable
$markdown += @'
```
@@ -201,6 +201,10 @@ All other versions are saved but not installed.
'@
$markdown += New-MDNewLine
+$markdown += New-MDHeader "Powershell Modules" -Level 4
+$markdown += Get-PowerShellModules | New-MDTable
+$markdown += New-MDNewLine
+
# Android section
$androidInstalledPackages = Get-AndroidInstalledPackages
diff --git a/images/win/scripts/Tests/PowerShellModules.Tests.ps1 b/images/win/scripts/Tests/PowerShellModules.Tests.ps1
index bd1113301..c4a9be861 100644
--- a/images/win/scripts/Tests/PowerShellModules.Tests.ps1
+++ b/images/win/scripts/Tests/PowerShellModules.Tests.ps1
@@ -1,3 +1,27 @@
+Describe "PowerShellModules" {
+ $modules = (Get-ToolsetContent).powershellModules
+ $withoutVersionsModules = $modules | Where-Object {-not $_.versions} | ForEach-Object {
+ @{moduleName = $_.name}
+ }
+
+ $withVersionsModules = $modules | Where-Object {$_.versions} | ForEach-Object {
+ $moduleName = $_.name
+ $_.versions | ForEach-Object {
+ @{moduleName = $moduleName; expectedVersion = $_}
+ }
+ }
+
+ It " is installed" -TestCases $withoutVersionsModules {
+ Get-Module -Name $moduleName -ListAvailable | Should -BeTrue
+ }
+
+ if ($withVersionsModules) {
+ It " with is installed" -TestCases $withVersionsModules {
+ (Get-Module -Name $moduleName -ListAvailable).Version -contains $expectedVersion | Should -BeTrue
+ }
+ }
+}
+
Describe "AzureModules" {
$modules = (Get-ToolsetContent).azureModules
$modulesRootPath = $env:PSMODULES_ROOT_FOLDER
diff --git a/images/win/toolsets/toolset-2016.json b/images/win/toolsets/toolset-2016.json
index 41d519b50..96f09bd11 100644
--- a/images/win/toolsets/toolset-2016.json
+++ b/images/win/toolsets/toolset-2016.json
@@ -75,6 +75,14 @@
]
}
],
+ "powershellModules": [
+ {"name": "DockerMsftProvider"},
+ {"name": "MarkdownPS"},
+ {"name": "Pester"},
+ {"name": "PowerShellGet"},
+ {"name": "PSWindowsUpdate"},
+ {"name": "SqlServer"}
+ ],
"azureModules": [
{
"name": "azurerm",
diff --git a/images/win/toolsets/toolset-2019.json b/images/win/toolsets/toolset-2019.json
index 73bc2f1de..0d0dfa8b8 100644
--- a/images/win/toolsets/toolset-2019.json
+++ b/images/win/toolsets/toolset-2019.json
@@ -84,6 +84,14 @@
]
}
],
+ "powershellModules": [
+ {"name": "DockerMsftProvider"},
+ {"name": "MarkdownPS"},
+ {"name": "Pester"},
+ {"name": "PowerShellGet"},
+ {"name": "PSWindowsUpdate"},
+ {"name": "SqlServer"}
+ ],
"azureModules": [
{
"name": "azurerm",