├── nme
├── bicep
│ └── nested_pid_8c1c30c0_3e0a_4655_9e05_51dea63a0e32_partnercenter.bicep
└── terraform
│ ├── _resources
│ └── nerdio.png
│ ├── sig.tf
│ ├── providers.tf
│ ├── versions.tf
│ ├── rg.tf
│ ├── private-dns.tf
│ ├── data.tf
│ ├── role-assignments.tf
│ └── vnet.tf
├── actions
├── apps.png
├── core
│ ├── Restart-Step.ps1
│ ├── 203_MicrosoftOutlook.ps1
│ ├── 100_MicrosoftVcRedists.ps1
│ ├── 012_WindowsUpdate.ps1
│ ├── 011_SupportFunctions.ps1
│ ├── 213_MicrosoftWindowsApp.ps1
│ ├── 103_MicrosoftNET.ps1
│ ├── 214_MicrosoftAzureCLI.ps1
│ ├── 215_MicrosoftPowerShell.ps1
│ └── 212_MicrosoftSQLServerManagementStudio.ps1
├── tweaks
│ ├── Invoke-DefenderFullScan.ps1
│ ├── Invoke-DefenderQuickScan.ps1
│ ├── Enable-TimeZoneRedirection.ps1
│ ├── Disable-FSLogixProfileContainer.ps1
│ ├── Disable-WindowsUpdate.ps1
│ ├── Set-WindowsUITweaks.ps1
│ ├── Enable-IgnoreRemoteKeyboardLayout.ps1
│ ├── Remove-IgnoreRemoteKeyboardLayout.ps1
│ ├── Remove-CitrixWorkspaceAppStartup.ps1
│ ├── Remove-WinRmRemoting.ps1
│ ├── Set-DefenderEndpointTag.ps1
│ ├── Remove-AdobeAcrobatReader.ps1
│ ├── Set-RdpFrameRate.ps1
│ ├── Remove-Directory.ps1
│ ├── Install-FSLogixAppMaskingRuleset.ps1
│ ├── Set-AppLockerPolicyConfig.ps1
│ └── Enable-RDPShortpath.ps1
├── tools
│ ├── Set-HybridAzureADJoin.ps1
│ ├── Uninstall-MicrosoftAzurePipelinesAgent.ps1
│ ├── Set-FSLogixStorageAccount.ps1
│ ├── Install-Pester.ps1
│ └── Install-MicrosoftAzurePipelinesAgent.ps1
├── 3rdparty
│ ├── 405_pdfforgePDFCreator.ps1
│ ├── 420_1Password.ps1
│ ├── 402_ZoomMeetings.ps1
│ ├── 411_draw.io.ps1
│ ├── 408_RemoteDesktopAnalyzer.ps1
│ └── 404_NotepadPlusPlus.ps1
└── optimise
│ └── Remove-UScheduleKeys.ps1
├── .vscode
├── extensions.json
└── settings.json
├── .github
├── FUNDING.yml
└── dependabot.yml
├── migrate
└── img
│ ├── citrix-installed.png
│ ├── citrix-noagents.png
│ ├── omnissa-installed.png
│ ├── omnissa-noagents.png
│ ├── microsoft-installed.png
│ ├── uninstall-citrixagents.png
│ └── uninstall-omnissaagents.png
├── variables
├── SecureVars.json
├── README.md
├── locale.json
└── NerdioManagerVariables.json
├── apps
├── configs
│ ├── AppLockerRules-20231114-0803-Enforce.xml
│ └── Redirections.xml
└── appv
│ ├── Install-JGraphDrawIO.ps1
│ ├── Install-ImageGlass.ps1
│ ├── Install-NotepadPlusPlus.ps1
│ ├── Install-VLCMediaPlayer.ps1
│ ├── Install-Paint.NET.ps1
│ ├── Install-FoxitPDFReader.ps1
│ └── Install-Greenshot.ps1
├── shell-apps
├── Microsoft
│ ├── AptosFont
│ │ ├── Uninstall.ps1
│ │ ├── Detect.ps1
│ │ └── Definition.json
│ ├── WindowsApp
│ │ ├── Install.ps1
│ │ ├── Uninstall.ps1
│ │ ├── Definition.json
│ │ └── Detect.ps1
│ ├── NETLTS
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Detect.ps1
│ │ └── Uninstall.ps1
│ ├── VisualC++2022x64
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ └── Uninstall.ps1
│ ├── VisualC++2022x86
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ └── Uninstall.ps1
│ ├── SQLServerManagementStudio
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Detect.ps1
│ │ └── Uninstall.ps1
│ ├── EdgeWebView2
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Detect.ps1
│ │ └── Uninstall.ps1
│ ├── VisualStudioCode
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Detect.ps1
│ │ └── Uninstall.ps1
│ ├── SupportCenter
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Uninstall.ps1
│ │ └── Detect.ps1
│ ├── PowerShell
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Detect.ps1
│ │ └── Uninstall.ps1
│ ├── AvdRtcService
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Uninstall.ps1
│ │ └── Detect.ps1
│ ├── AzureCLI
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Detect.ps1
│ │ └── Uninstall.ps1
│ ├── AvdMultimediaRedirection
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Detect.ps1
│ │ └── Uninstall.ps1
│ ├── Edge
│ │ ├── Uninstall.ps1
│ │ ├── Definition.json
│ │ └── Detect.ps1
│ ├── Teams
│ │ ├── Definition.json
│ │ ├── Detect.ps1
│ │ └── Uninstall.ps1
│ ├── OneDrive
│ │ ├── Definition.json
│ │ ├── Install.ps1
│ │ └── Uninstall.ps1
│ ├── PowerToys
│ │ ├── Definition.json
│ │ ├── Detect.ps1
│ │ └── Uninstall.ps1
│ └── FSLogixApps
│ │ ├── Definition.json
│ │ ├── Install.ps1
│ │ ├── Detect.ps1
│ │ └── Uninstall.ps1
├── stealthpuppy
│ └── defaults
│ │ ├── Uninstall.ps1
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ └── Detect.ps1
├── Audacity
│ ├── Install.ps1
│ ├── Definition.json
│ ├── Uninstall.ps1
│ └── Detect.ps1
├── Zoom
│ └── Workplace
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Uninstall.ps1
│ │ └── Detect.ps1
├── README.md
├── Obsidian
│ ├── Install.ps1
│ ├── Definition.json
│ ├── Uninstall.ps1
│ └── Detect.ps1
├── dotPDN
│ └── Paint.NET
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Uninstall.ps1
│ │ └── Detect.ps1
├── JGraph
│ └── draw.io
│ │ ├── Install.ps1
│ │ ├── Definition.json
│ │ ├── Uninstall.ps1
│ │ └── Detect.ps1
├── Foxit
│ └── PDFReader
│ │ ├── Definition.json
│ │ ├── Install.ps1
│ │ ├── Uninstall.ps1
│ │ └── Detect.ps1
├── Google
│ └── Chrome
│ │ ├── Definition.json
│ │ ├── Uninstall.ps1
│ │ └── Detect.ps1
├── Adobe
│ └── AcrobatReader
│ │ ├── Definition.json
│ │ ├── Uninstall.ps1
│ │ └── Detect.ps1
└── ImageGlass
│ ├── Definition.json
│ ├── Install.ps1
│ ├── Uninstall.ps1
│ └── Detect.ps1
├── import
└── Detect.json
├── .devops
└── pipelines
│ └── validate-apps.yml
├── README.md
└── .gitignore
/nme/bicep/nested_pid_8c1c30c0_3e0a_4655_9e05_51dea63a0e32_partnercenter.bicep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/actions/apps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaronparker/nerdio-actions/HEAD/actions/apps.png
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "ms-vscode.powershell"
4 | ]
5 | }
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: aaronparker
4 | ko_fi: stealthpuppy
5 |
--------------------------------------------------------------------------------
/migrate/img/citrix-installed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaronparker/nerdio-actions/HEAD/migrate/img/citrix-installed.png
--------------------------------------------------------------------------------
/migrate/img/citrix-noagents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaronparker/nerdio-actions/HEAD/migrate/img/citrix-noagents.png
--------------------------------------------------------------------------------
/migrate/img/omnissa-installed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaronparker/nerdio-actions/HEAD/migrate/img/omnissa-installed.png
--------------------------------------------------------------------------------
/migrate/img/omnissa-noagents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaronparker/nerdio-actions/HEAD/migrate/img/omnissa-noagents.png
--------------------------------------------------------------------------------
/migrate/img/microsoft-installed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaronparker/nerdio-actions/HEAD/migrate/img/microsoft-installed.png
--------------------------------------------------------------------------------
/nme/terraform/_resources/nerdio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaronparker/nerdio-actions/HEAD/nme/terraform/_resources/nerdio.png
--------------------------------------------------------------------------------
/migrate/img/uninstall-citrixagents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaronparker/nerdio-actions/HEAD/migrate/img/uninstall-citrixagents.png
--------------------------------------------------------------------------------
/migrate/img/uninstall-omnissaagents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaronparker/nerdio-actions/HEAD/migrate/img/uninstall-omnissaagents.png
--------------------------------------------------------------------------------
/variables/SecureVars.json:
--------------------------------------------------------------------------------
1 | {
2 | "VariablesList": "https://stybluynyickph2.blob.core.windows.net/variables/NerdioManagerVariables.json"
3 | }
--------------------------------------------------------------------------------
/actions/core/Restart-Step.ps1:
--------------------------------------------------------------------------------
1 | #description: Installs the latest Microsoft PowerShell
2 | #execution mode: IndividualWithRestart
3 | #tags: Image, Restart
4 |
--------------------------------------------------------------------------------
/apps/configs/AppLockerRules-20231114-0803-Enforce.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaronparker/nerdio-actions/HEAD/apps/configs/AppLockerRules-20231114-0803-Enforce.xml
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AptosFont/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | Get-ChildItem -Path "$Env:SystemRoot\Fonts\Aptos*" | ForEach-Object {
2 | $Context.Log("Removing font file: $($_.FullName)")
3 | Remove-Item -Path $_.FullName -Force -ErrorAction "SilentlyContinue"
4 | }
5 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # Set update schedule for GitHub Actions
2 | version: 2
3 | updates:
4 | - package-ecosystem: "github-actions"
5 | directory: "/"
6 | schedule:
7 | # Check for updates to GitHub Actions every weekday
8 | interval: "daily"
9 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/WindowsApp/Install.ps1:
--------------------------------------------------------------------------------
1 | $params = @{
2 | PackagePath = $Context.GetAttachedBinary()
3 | Online = $true
4 | SkipLicense = $true
5 | ErrorAction = "Stop"
6 | }
7 | Add-AppxProvisionedPackage @params
8 | $Context.Log("Install complete")
9 |
--------------------------------------------------------------------------------
/shell-apps/stealthpuppy/defaults/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | $Context.Log("Uninstalling Windows Enterprise Defaults")
2 | Get-ChildItem -Path $PWD -Include "Remove-Defaults.ps1" -Recurse -File | ForEach-Object {
3 | $Context.Log("Executing: $($_.FullName)")
4 | & $_.FullName
5 | }
6 | $Context.Log("Uninstall complete")
7 |
--------------------------------------------------------------------------------
/actions/tweaks/Invoke-DefenderFullScan.ps1:
--------------------------------------------------------------------------------
1 | #description: Runs a Microsoft Defender antivirus quick scan. Use in a desktop image to ensure the scan data is up to date
2 | #execution mode: Combined
3 | #tags: Antivirus, Image
4 |
5 | Update-MpSignature -UpdateSource "MicrosoftUpdateServer"
6 | Start-MpScan -ScanType "FullScan"
7 |
--------------------------------------------------------------------------------
/actions/tweaks/Invoke-DefenderQuickScan.ps1:
--------------------------------------------------------------------------------
1 | #description: Runs a Microsoft Defender antivirus quick scan. Use in a desktop image to ensure the scan data is up to date
2 | #execution mode: Combined
3 | #tags: Antivirus, Image
4 |
5 | Update-MpSignature -UpdateSource "MicrosoftUpdateServer"
6 | Start-MpScan -ScanType "QuickScan"
7 |
--------------------------------------------------------------------------------
/nme/terraform/sig.tf:
--------------------------------------------------------------------------------
1 | resource "azurerm_shared_image_gallery" "nerdio" {
2 | name = "${lower(replace(var.base_name, "-", ""))}sig"
3 | resource_group_name = local.resource_group_name
4 | location = local.resource_group_location
5 | description = "Images for Virtual Desktops"
6 |
7 | tags = var.tags
8 | }
9 |
--------------------------------------------------------------------------------
/variables/README.md:
--------------------------------------------------------------------------------
1 | # Example Variable
2 |
3 | Files are are example variable data used by some scripts.
4 |
5 | To format the JSON data for pasting into the Nerdio Manager secure variables values, use the following to compress the JSON.
6 |
7 | ```powershell
8 | Get-Content -Path ./locale.json | ConvertFrom-Json | ConvertTo-Json -Compress | Set-Clipboard
9 | ```
10 |
--------------------------------------------------------------------------------
/actions/tweaks/Enable-TimeZoneRedirection.ps1:
--------------------------------------------------------------------------------
1 | #description: Enable time zone redirection in RDP sessions
2 | #execution mode: Combined
3 | #tags: Keyboard, Language, Image
4 |
5 | # Enable time zone redirection - this can be configure via policy as well
6 | reg add "HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services" /v fEnableTimeZoneRedirection /d 1 /t REG_DWORD /f
7 |
--------------------------------------------------------------------------------
/actions/tweaks/Disable-FSLogixProfileContainer.ps1:
--------------------------------------------------------------------------------
1 | #description: Disables the Microsoft FSLogix Profile Container. Reboot required.
2 | #execution mode: Combined
3 | #tags: FSLogix, Image
4 |
5 | # https://learn.microsoft.com/en-us/fslogix/reference-configuration-settings?tabs=profiles#enabled
6 | reg add "HKLM\SOFTWARE\FSLogix\Profiles" /v "Enabled" /t "REG_DWORD" /d 0 /f | Out-Null
7 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/NETLTS/Install.ps1:
--------------------------------------------------------------------------------
1 | $params = @{
2 | FilePath = $Context.GetAttachedBinary()
3 | ArgumentList = "/install /quiet /norestart"
4 | Wait = $true
5 | PassThru = $true
6 | NoNewWindow = $true
7 | ErrorAction = "Stop"
8 | }
9 | $result = Start-Process @params
10 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
11 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/VisualC++2022x64/Install.ps1:
--------------------------------------------------------------------------------
1 | $params = @{
2 | FilePath = $Context.GetAttachedBinary()
3 | ArgumentList = "/install /passive /norestart"
4 | Wait = $true
5 | NoNewWindow = $true
6 | PassThru = $true
7 | ErrorAction = "Stop"
8 | }
9 | $result = Start-Process @params
10 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
11 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/VisualC++2022x86/Install.ps1:
--------------------------------------------------------------------------------
1 | $params = @{
2 | FilePath = $Context.GetAttachedBinary()
3 | ArgumentList = "/install /passive /norestart"
4 | Wait = $true
5 | NoNewWindow = $true
6 | PassThru = $true
7 | ErrorAction = "Stop"
8 | }
9 | $result = Start-Process @params
10 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
11 |
--------------------------------------------------------------------------------
/actions/tweaks/Disable-WindowsUpdate.ps1:
--------------------------------------------------------------------------------
1 | #description: Disables Windows Update
2 | #execution mode: Combined
3 | #tags: Update, Image
4 |
5 | $RegPath = "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate\AU"
6 | if (-not (Test-Path -Path $RegPath)) { New-Item -Path $RegPath -Force }
7 | Set-ItemProperty -Path $RegPath -Name NoAutoUpdate -Value 1
8 | Set-ItemProperty -Path $RegPath -Name AUOptions -Value 3
9 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/SQLServerManagementStudio/Install.ps1:
--------------------------------------------------------------------------------
1 | $params = @{
2 | FilePath = $Context.GetAttachedBinary()
3 | ArgumentList = "/install /quiet /norestart"
4 | Wait = $true
5 | PassThru = $true
6 | NoNewWindow = $true
7 | ErrorAction = "Stop"
8 | }
9 | $result = Start-Process @params
10 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
11 |
--------------------------------------------------------------------------------
/actions/tweaks/Set-WindowsUITweaks.ps1:
--------------------------------------------------------------------------------
1 | #description: Configure Windows UI settings
2 | #execution mode: Combined
3 | #tags: UI
4 |
5 | # Add registry keys
6 | reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes" /v "MS Shell Dlg" /t "REG_SZ" /d "Tahoma" /f | Out-Null
7 | reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes" /v "MS Shell Dlg 2" /t "REG_SZ" /d "Tahoma" /f | Out-Null
8 |
--------------------------------------------------------------------------------
/shell-apps/Audacity/Install.ps1:
--------------------------------------------------------------------------------
1 | $params = @{
2 | FilePath = $Context.GetAttachedBinary()
3 | ArgumentList = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- /MERGETASKS=`"!desktopicon`""
4 | Wait = $true
5 | PassThru = $true
6 | NoNewWindow = $true
7 | ErrorAction = "Stop"
8 | }
9 | $result = Start-Process @params
10 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
11 |
--------------------------------------------------------------------------------
/nme/terraform/providers.tf:
--------------------------------------------------------------------------------
1 |
2 | provider "azurerm" {
3 | storage_use_azuread = true
4 | features {
5 | application_insights {
6 | disable_generated_rule = true
7 | }
8 | key_vault {
9 | purge_soft_delete_on_destroy = true
10 | recover_soft_deleted_key_vaults = true
11 | }
12 | log_analytics_workspace {
13 | permanently_delete_on_destroy = true
14 | }
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/EdgeWebView2/Install.ps1:
--------------------------------------------------------------------------------
1 | $Context.Log("Installing package: $($Context.GetAttachedBinary())")
2 | $params = @{
3 | FilePath = $Context.GetAttachedBinary()
4 | ArgumentList = "/silent /install"
5 | Wait = $true
6 | PassThru = $true
7 | NoNewWindow = $true
8 | ErrorAction = "Stop"
9 | }
10 | $result = Start-Process @params
11 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
12 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/WindowsApp/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $PackageFamilyName = "MicrosoftCorporationII.Windows365_8wekyb3d8bbwe"
3 |
4 | Get-AppxPackage -AllUsers | Where-Object { $_.PackageFamilyName -eq $PackageFamilyName } | ForEach-Object {
5 | $Context.Log("Removing existing AppX package: $($_.Name)")
6 | $_ | Remove-AppxPackage -AllUsers -ErrorAction "Stop"
7 | }
8 | Start-Sleep -Seconds 10
9 | $Context.Log("Uninstall complete")
10 |
--------------------------------------------------------------------------------
/actions/tweaks/Enable-IgnoreRemoteKeyboardLayout.ps1:
--------------------------------------------------------------------------------
1 | #description: Ignore the keyboard layout of the endpoint and keep the selected input language in the AVD session host
2 | #execution mode: Combined
3 | #tags: Keyboard, Language, Image
4 |
5 | # Add the registry value
6 | # https://dennisspan.com/solving-keyboard-layout-issues-in-an-ica-or-rdp-session/
7 | reg add "HKLM\SYSTEM\CurrentControlSet\Control\Keyboard Layout" /v "IgnoreRemoteKeyboardLayout" /d 1 /t "REG_DWORD" /f
8 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/VisualStudioCode/Install.ps1:
--------------------------------------------------------------------------------
1 | $params = @{
2 | FilePath = $Context.GetAttachedBinary()
3 | ArgumentList = "/VERYSILENT /NOCLOSEAPPLICATIONS /NORESTARTAPPLICATIONS /NORESTART /SP- /SUPPRESSMSGBOXES /MERGETASKS=!runcode"
4 | Wait = $true
5 | NoNewWindow = $true
6 | PassThru = $true
7 | ErrorAction = "Stop"
8 | }
9 | $result = Start-Process @params
10 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
11 |
--------------------------------------------------------------------------------
/actions/tweaks/Remove-IgnoreRemoteKeyboardLayout.ps1:
--------------------------------------------------------------------------------
1 | #description: Removes the setting to ignore the keyboard layout of the endpoint and keep the selected input language in the AVD session host
2 | #execution mode: Combined
3 | #tags: Keyboard, Language, Image
4 |
5 | # Remove the registry value
6 | # https://dennisspan.com/solving-keyboard-layout-issues-in-an-ica-or-rdp-session/
7 | reg delete "HKLM\SYSTEM\CurrentControlSet\Control\Keyboard Layout" /v "IgnoreRemoteKeyboardLayout" /f | Out-Null
8 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/SupportCenter/Install.ps1:
--------------------------------------------------------------------------------
1 | $Context.Log("Installing package: $($Context.GetAttachedBinary())")
2 | $params = @{
3 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
4 | ArgumentList = "/package `"$($Context.GetAttachedBinary())`" /quiet"
5 | Wait = $true
6 | NoNewWindow = $true
7 | PassThru = $true
8 | ErrorAction = "Stop"
9 | }
10 | $result = Start-Process @params
11 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
12 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/PowerShell/Install.ps1:
--------------------------------------------------------------------------------
1 | $Context.Log("Installing package: $($Context.GetAttachedBinary())")
2 | $params = @{
3 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
4 | ArgumentList = "/package $($Context.GetAttachedBinary()) /quiet /norestart"
5 | Wait = $true
6 | PassThru = $true
7 | NoNewWindow = $true
8 | ErrorAction = "Stop"
9 | }
10 | $result = Start-Process @params
11 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
12 |
--------------------------------------------------------------------------------
/actions/tweaks/Remove-CitrixWorkspaceAppStartup.ps1:
--------------------------------------------------------------------------------
1 | #description: Remove the Citrix Workspace app processes from the Run registry key
2 | #execution mode: Combined
3 | #tags: Citrix
4 |
5 | reg delete "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run" /v "AnalyticsSrv" /f | Out-Null
6 | reg delete "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run" /v "ConnectionCenter" /f | Out-Null
7 | reg delete "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run" /v "Redirector" /f | Out-Null
8 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AvdRtcService/Install.ps1:
--------------------------------------------------------------------------------
1 | $Context.Log("Installing package: $($Context.GetAttachedBinary())")
2 | $params = @{
3 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
4 | ArgumentList = "/package `"$($Context.GetAttachedBinary())`" /quiet /norestart"
5 | Wait = $true
6 | NoNewWindow = $true
7 | PassThru = $true
8 | ErrorAction = "Stop"
9 | }
10 | $result = Start-Process @params
11 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
12 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AzureCLI/Install.ps1:
--------------------------------------------------------------------------------
1 | $Context.Log("Installing package: $($Context.GetAttachedBinary())")
2 | $params = @{
3 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
4 | ArgumentList = "/package $($Context.GetAttachedBinary()) /quiet /norestart ALLUSERS=1"
5 | Wait = $true
6 | PassThru = $true
7 | NoNewWindow = $true
8 | ErrorAction = "Stop"
9 | }
10 | $result = Start-Process @params
11 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
12 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AvdMultimediaRedirection/Install.ps1:
--------------------------------------------------------------------------------
1 | $Context.Log("Installing package: $($Context.GetAttachedBinary())")
2 | $params = @{
3 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
4 | ArgumentList = "/package `"$($Context.GetAttachedBinary())`" /quiet /norestart"
5 | Wait = $true
6 | NoNewWindow = $true
7 | PassThru = $true
8 | ErrorAction = "Stop"
9 | }
10 | $result = Start-Process @params
11 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
12 |
--------------------------------------------------------------------------------
/actions/tweaks/Remove-WinRmRemoting.ps1:
--------------------------------------------------------------------------------
1 | #description: Disables WinRM firewall rules and PS Remoting. Only use if you need to disable these features
2 | #execution mode: Combined
3 | #tags: Language, Image
4 |
5 | #region Disable WinRM firewall rules and disable PS Remoting
6 | # https://github.com/Azure/RDS-Templates/issues/435
7 | # https://qiita.com/fujinon1109/items/440c614338fe2535b09e
8 |
9 | Get-NetFirewallRule -DisplayGroup "Windows Remote Management" | Disable-NetFirewallRule
10 | Disable-PSRemoting -Force
11 | #endregion
12 |
--------------------------------------------------------------------------------
/shell-apps/Zoom/Workplace/Install.ps1:
--------------------------------------------------------------------------------
1 | $Context.Log("Installing package: $($Context.GetAttachedBinary())")
2 | $params = @{
3 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
4 | ArgumentList = "/package `"$($Context.GetAttachedBinary())`" zSilentStart=false zNoDesktopShortCut=true ALLUSERS=1 /quiet"
5 | Wait = $true
6 | PassThru = $true
7 | NoNewWindow = $true
8 | ErrorAction = "Stop"
9 | }
10 | $result = Start-Process @params
11 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
12 |
--------------------------------------------------------------------------------
/nme/terraform/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 1.3"
3 |
4 | required_providers {
5 | azuread = {
6 | source = "hashicorp/azuread"
7 | version = "~> 2.31"
8 | }
9 |
10 | azurerm = {
11 | source = "hashicorp/azurerm"
12 | version = "~> 3.36"
13 | }
14 |
15 | time = {
16 | source = "hashicorp/time"
17 | version = "~> 0.9"
18 | }
19 |
20 | azapi = {
21 | source = "azure/azapi"
22 | version = "~> 1.10.0"
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/actions/tweaks/Set-DefenderEndpointTag.ps1:
--------------------------------------------------------------------------------
1 | #description: Sets a tag for Microsoft Defender for Endpoint
2 | #execution mode: Combined
3 | #tags: MDE
4 |
5 | # https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/machine-tags?view=o365-worldwide
6 |
7 | # Set a tag value
8 | if ($null -eq $SecureVars.MdeTag) {
9 | $TagValue = "AVD"
10 | }
11 | else {
12 | $TagValue = $SecureVars.MdeTag
13 | }
14 |
15 | # Add the tag value to the registry
16 | reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows Advanced Threat Protection\DeviceTagging" /v "Group" /t "REG_SZ" /d $TagValue /f | Out-Null
17 |
--------------------------------------------------------------------------------
/actions/tweaks/Remove-AdobeAcrobatReader.ps1:
--------------------------------------------------------------------------------
1 | #description: Removes policies that Adobe Acrobat into read-only mode so that it runs as Reader
2 | #execution mode: Combined
3 | #tags: Adobe, Acrobat, PDF
4 |
5 | # https://helpx.adobe.com/au/enterprise/kb/acrobat-64-bit-for-enterprises.html
6 | reg delete "HKLM\SOFTWARE\Policies\Adobe\Adobe Acrobat\DC\FeatureLockDown" /v "bIsSCReducedModeEnforcedEx" /f | Out-Null
7 | reg delete "HKLM\SOFTWARE\Policies\Adobe\Adobe Acrobat\DC\FeatureLockDown\cIPM" /v "bDontShowMsgWhenViewingDoc" /f | Out-Null
8 | reg delete "HKLM\SOFTWARE\Policies\Adobe\Adobe Acrobat\DC\FeatureLockDown" /v "bAcroSuppressUpsell" /f | Out-Null
9 |
--------------------------------------------------------------------------------
/actions/tweaks/Set-RdpFrameRate.ps1:
--------------------------------------------------------------------------------
1 | #description: Set a specified framerate for RDP - sets framerate to 60 FPS by default, unless RdpFrameRate is passed via Secure Variables
2 | #execution mode: Combined
3 | #tags: RDP, Framerate
4 |
5 | # https://learn.microsoft.com/en-us/troubleshoot/windows-server/remote/frame-rate-limited-to-30-fps
6 |
7 | if ($null -eq $SecureVars.RdpFrameRate) {
8 | $RdpFrameRate = "15"
9 | }
10 | else {
11 | $RdpFrameRate = $SecureVars.RdpFrameRate
12 | }
13 |
14 | # Add registry keys
15 | reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations" /v "DWMFRAMEINTERVAL" /t "REG_DWORD" /d $RdpFrameRate /f | Out-Null
16 |
--------------------------------------------------------------------------------
/shell-apps/README.md:
--------------------------------------------------------------------------------
1 | # Nerdio Manager Shell Apps
2 |
3 | Note: this code is provided as-is, without warranty or support of any kind.
4 |
5 | A list of definitions for Nerdio Manager Shell Apps - these include detection, install and uninstall scripts.
6 |
7 | ## Automation
8 |
9 | Included here is a proof-of-concept for automating the import for Shell Apps and versions - requires Nerdio Manager for Enterprise 7.2+:
10 |
11 | * `NerdioShellApps.psm1` - a module with functions required for automating the import of Shell Apps. This depends on the [Evergreen](https://stealthpuppy.com/evergreen)
12 | * `Create-ShellApps.ps1` - a sample script for importing a selection of Shell Apps into Nerdio Manager
13 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "Addin",
4 | "ALLUSER",
5 | "Audiosrv",
6 | "AUTOACTIVATE",
7 | "bigendianunicode",
8 | "captutre",
9 | "CHROMEEXT",
10 | "Codecov",
11 | "DISABLEDESKTOPSHORTCUT",
12 | "DONOTCREATEDESKTOPSHORTCUT",
13 | "DWORD",
14 | "Foxit",
15 | "Greenshot",
16 | "HKEY",
17 | "Hotfixes",
18 | "Lync",
19 | "Nerdio",
20 | "Omnissa",
21 | "RUNAPPLICATION",
22 | "Shortpath",
23 | "THUMBNAILPREVIEW",
24 | "windowsdesktop",
25 | "Zstandard",
26 | "zyborg"
27 | ],
28 | "pester.autoRunOnSave": false
29 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AptosFont/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "$Env:SystemRoot\Fonts\Aptos.ttf"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | if (Test-Path -Path $FilePath) {
14 | return $Context.TargetVersion
15 | }
16 | else {
17 | $Context.Log("File does not exist at: $($FilePath)")
18 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/shell-apps/Obsidian/Install.ps1:
--------------------------------------------------------------------------------
1 | $params = @{
2 | FilePath = $Context.GetAttachedBinary()
3 | ArgumentList = "/S /ALLUSERS=1 /D=`"${Env:ProgramFiles}\Obsidian`""
4 | Wait = $true
5 | PassThru = $true
6 | NoNewWindow = $true
7 | ErrorAction = "Stop"
8 | }
9 | $result = Start-Process @params
10 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
11 |
12 | # Delete public desktop shortcut
13 | Start-Sleep -Seconds 5
14 | $Shortcuts = @("$Env:Public\Desktop\Obsidian.lnk")
15 | Get-Item -Path $Shortcuts -ErrorAction "SilentlyContinue" | `
16 | ForEach-Object { $Context.Log("Remove file: $($_.FullName)"); Remove-Item -Path $_.FullName -Force -ErrorAction "SilentlyContinue" }
17 |
--------------------------------------------------------------------------------
/nme/terraform/rg.tf:
--------------------------------------------------------------------------------
1 | resource "azurerm_resource_group" "nerdio" {
2 | count = var.create_resource_group ? 1 : 0
3 | name = var.resource_group_name != "" ? var.resource_group_name : "${lower(var.base_name)}-rg"
4 | location = var.location
5 | tags = var.tags
6 | }
7 |
8 | data "azurerm_resource_group" "existing" {
9 | count = var.create_resource_group ? 0 : 1
10 | name = var.resource_group_name
11 | }
12 |
13 | locals {
14 | resource_group_name = var.create_resource_group ? azurerm_resource_group.nerdio[0].name : data.azurerm_resource_group.existing[0].name
15 | resource_group_location = var.create_resource_group ? azurerm_resource_group.nerdio[0].location : data.azurerm_resource_group.existing[0].location
16 | }
17 |
--------------------------------------------------------------------------------
/actions/tools/Set-HybridAzureADJoin.ps1:
--------------------------------------------------------------------------------
1 | #description: Enables Hybrid Entra ID join registry entries
2 | #execution mode: Combined
3 | #tags: Image, HAADJ
4 |
5 | # https://learn.microsoft.com/en-us/azure/active-directory/devices/hybrid-azuread-join-control
6 |
7 | if ($null -eq $SecureVars.AzureADTenantName) {
8 | throw "AzureADTenantName not set"
9 | }
10 |
11 | if ($null -eq $SecureVars.AzureADTenantId) {
12 | throw "AzureADTenantId not set"
13 | }
14 |
15 | # Add registry keys
16 | reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\CDJ\AAD" /v "TenantName" /t "REG_SZ" /d $SecureVars.AzureADTenantName /f | Out-Null
17 | reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\CDJ\AAD" /v "TenantId" /t "REG_SZ" /d $SecureVars.AzureADTenantId /f | Out-Null
18 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/Edge/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | # Warning - uninstalling Microsoft Edge is probably not a good idea, but this is how you do it.
2 |
3 | # Uninstall Microsoft Edge using the setup.exe in the Edge application directory
4 | $SetupExe = Get-ChildItem -Path "${Env:ProgramFiles(x86)}\Microsoft\Edge\Application" -Recurse -Include "setup.exe" | `
5 | Select-Object -First 1
6 |
7 | $params = @{
8 | FilePath = $SetupExe.FullName
9 | ArgumentList = "setup.exe --uninstall --system-level --verbose-logging --force-uninstall"
10 | Wait = $true
11 | PassThru = $true
12 | NoNewWindow = $true
13 | ErrorAction = "Stop"
14 | }
15 | $result = Start-Process @params
16 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
17 |
--------------------------------------------------------------------------------
/shell-apps/dotPDN/Paint.NET/Install.ps1:
--------------------------------------------------------------------------------
1 | Get-ChildItem -Path $PWD -Recurse -Include "paint.*msi" | ForEach-Object {
2 | $Context.Log("Installing Paint.NET from: $($_.FullName)")
3 | $params = @{
4 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
5 | ArgumentList = "/package `"$($_.FullName)`" DESKTOPSHORTCUT=0 CHECKFORUPDATES=0 CHECKFORBETAS=0 /quiet"
6 | Wait = $true
7 | NoNewWindow = $true
8 | PassThru = $true
9 | ErrorAction = "Stop"
10 | }
11 | $result = Start-Process @params
12 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
13 | }
14 |
15 | Start-Sleep -Seconds 5
16 | $Shortcuts = @("$Env:Public\Desktop\Paint.NET.lnk")
17 | Remove-Item -Path $Shortcuts -Force -ErrorAction "Ignore"
18 |
--------------------------------------------------------------------------------
/shell-apps/stealthpuppy/defaults/Install.ps1:
--------------------------------------------------------------------------------
1 | # Configure the environment
2 | $ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
3 | $InformationPreference = [System.Management.Automation.ActionPreference]::Continue
4 | $ProgressPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue
5 | [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
6 |
7 | # Unzip and run all Install-Defaults.ps1 scripts
8 | Expand-Archive -Path $Context.GetAttachedBinary() -DestinationPath $PWD -Force
9 | Get-ChildItem -Path $PWD -Include "Install-Defaults.ps1" -Recurse -File | ForEach-Object {
10 | $Context.Log("Executing: $($_.FullName)")
11 | & $_.FullName
12 | }
13 | $Context.Log("Install complete")
14 |
--------------------------------------------------------------------------------
/shell-apps/JGraph/draw.io/Install.ps1:
--------------------------------------------------------------------------------
1 | $Context.Log("Installing package: $($Context.GetAttachedBinary())")
2 | $params = @{
3 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
4 | ArgumentList = "/package $($Context.GetAttachedBinary()) /quiet /norestart ALLUSERS=1"
5 | Wait = $true
6 | PassThru = $true
7 | NoNewWindow = $true
8 | ErrorAction = "Stop"
9 | }
10 | $result = Start-Process @params
11 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
12 |
13 | # Post install configuration
14 | $Shortcuts = @("$Env:Public\Desktop\draw.io.lnk")
15 | Get-Item -Path $Shortcuts -ErrorAction "SilentlyContinue" | `
16 | ForEach-Object { $Context.Log("Remove file: $($_.FullName)"); Remove-Item -Path $_.FullName -Force -ErrorAction "SilentlyContinue" }
17 |
--------------------------------------------------------------------------------
/actions/tweaks/Remove-Directory.ps1:
--------------------------------------------------------------------------------
1 | #description: Removes a set of unnecessary directories
2 | #execution mode: Combined
3 | #tags: Cleanup
4 |
5 | # Remove paths that we should not need to leave around in the image
6 | # Remove paths that we should not need to leave around in the image
7 | Remove-Item -Path "$Env:SystemDrive\Apps" -Recurse -Force -ErrorAction "SilentlyContinue"
8 | Remove-Item -Path "$Env:SystemDrive\DeployAgent" -Recurse -Force -ErrorAction "SilentlyContinue"
9 | Remove-Item -Path "$Env:SystemDrive\Users\AgentInstall.txt" -Force -Confirm:$false -ErrorAction "SilentlyContinue"
10 | Remove-Item -Path "$Env:SystemDrive\Users\AgentBootLoaderInstall.txt" -Force -Confirm:$false -ErrorAction "SilentlyContinue"
11 | Remove-Item -Path "$Env:Public\Desktop\*.lnk" -Force -Confirm:$false -ErrorAction "SilentlyContinue"
12 |
--------------------------------------------------------------------------------
/apps/appv/Install-JGraphDrawIO.ps1:
--------------------------------------------------------------------------------
1 | #Requires -Modules Evergreen
2 | [System.String] $Path = "$Env:SystemDrive\Temp"
3 |
4 | Import-Module -Name "Evergreen" -Force
5 | $App = Get-EvergreenApp -Name "JGraphDrawIO" | Where-Object { $_.Type -eq "msi" } | Select-Object -First 1
6 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
7 |
8 | $params = @{
9 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
10 | ArgumentList = "/package `"$($OutFile.FullName)`" ALLUSERS=1 /quiet"
11 | NoNewWindow = $true
12 | Wait = $true
13 | PassThru = $true
14 | ErrorAction = "Stop"
15 | }
16 | Start-Process @params
17 |
18 | Start-Sleep -Seconds 5
19 | $Shortcuts = @("$Env:Public\Desktop\draw.io.lnk")
20 | Remove-Item -Path $Shortcuts -Force -ErrorAction "Ignore"
21 | #endregion
22 |
--------------------------------------------------------------------------------
/variables/locale.json:
--------------------------------------------------------------------------------
1 | {
2 | "australiaeast": {
3 | "Language": "en-AU",
4 | "TimeZone": "AUS Eastern Standard Time"
5 | },
6 | "australiasoutheast": {
7 | "Language": "en-AU",
8 | "TimeZone": "AUS Eastern Standard Time"
9 | },
10 | "westus": {
11 | "Language": "en-US",
12 | "TimeZone": "Pacific Standard Time"
13 | },
14 | "westus2": {
15 | "Language": "en-US",
16 | "TimeZone": "Pacific Standard Time"
17 | },
18 | "eastus": {
19 | "Language": "en-US",
20 | "TimeZone": "Eastern Standard Time"
21 | },
22 | "uksouth": {
23 | "Language": "en-GB",
24 | "TimeZone": "GMT Standard Time"
25 | },
26 | "ukwest": {
27 | "Language": "en-GB",
28 | "TimeZone": "GMT Standard Time"
29 | }
30 | }
--------------------------------------------------------------------------------
/shell-apps/Obsidian/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Obsidian",
3 | "description": "The free and flexible app for your private thoughts.",
4 | "isPublic": true,
5 | "publisher": "Obsidian",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "Obsidian",
25 | "filter": "$_.Type -eq \"exe\""
26 | }
27 | }
--------------------------------------------------------------------------------
/nme/terraform/private-dns.tf:
--------------------------------------------------------------------------------
1 | locals {
2 | pl_zones = {
3 | automation = "privatelink.azure-automation.net"
4 | keyvault = "privatelink.vaultcore.azure.net"
5 | sqlserver = "privatelink.database.windows.net"
6 | website = "privatelink.azurewebsites.net"
7 | }
8 | }
9 |
10 | resource "azurerm_private_dns_zone" "private_link" {
11 | for_each = local.pl_zones
12 |
13 | name = each.value
14 | resource_group_name = local.resource_group_name
15 | }
16 |
17 | resource "azurerm_private_dns_zone_virtual_network_link" "private_link" {
18 | for_each = azurerm_private_dns_zone.private_link
19 |
20 | name = azurerm_virtual_network.nerdio.name
21 | resource_group_name = local.resource_group_name
22 | private_dns_zone_name = each.value.name
23 | virtual_network_id = azurerm_virtual_network.nerdio.id
24 | }
25 |
--------------------------------------------------------------------------------
/shell-apps/Audacity/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Audacity",
3 | "description": "Audacity is a free, open source, cross-platform audio software for multi-track recording and editing.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "Audacity",
25 | "filter": "$_.Architecture -eq \"x64\""
26 | }
27 | }
--------------------------------------------------------------------------------
/actions/tools/Uninstall-MicrosoftAzurePipelinesAgent.ps1:
--------------------------------------------------------------------------------
1 | #description: Uninstalls the Microsoft Azure Pipelines agent.
2 | #execution mode: Combined
3 | #tags: Evergreen, Testing, DevOps
4 | #Requires -Modules Evergreen
5 | [System.String] $Path = "$Env:SystemDrive\agents"
6 |
7 | #region Script logic
8 | Push-Location -Path $Path
9 | $params = @{
10 | FilePath = "$Path\config.cmd"
11 | ArgumentList = "remove --unattended --auth pat --token `"$($SecureVars.DevOpsPat)`""
12 | Wait = $true
13 | NoNewWindow = $true
14 | PassThru = $true
15 | ErrorAction = "Stop"
16 | }
17 | Start-Process @params
18 |
19 | # Remove the C:\agents directory and the local user account used by the agent service
20 | Remove-Item -Path $Path -Recurse -Force -ErrorAction "SilentlyContinue"
21 | Remove-LocalUser -Name $SecureVars.DevOpsUser -Confirm:$false -ErrorAction "SilentlyContinue"
22 | #endregion
23 |
--------------------------------------------------------------------------------
/shell-apps/Foxit/PDFReader/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Foxit PDF Reader",
3 | "description": "Foxit PDF Reader is a free PDF viewer that allows you to view, print, and annotate PDF documents.",
4 | "isPublic": true,
5 | "publisher": "Foxit Software",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "FoxitReader",
25 | "filter": "$_.Language -eq \"English\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/JGraph/draw.io/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "draw.io",
3 | "description": "Work offline on your diagrams and save locally using the draw.io Desktop app for Windows.",
4 | "isPublic": true,
5 | "publisher": "JGraph",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "JGraphDrawIO",
25 | "filter": "$_.Architecture -eq \"x86\" -and $_.Type -eq \"msi\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/dotPDN/Paint.NET/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Paint.NET",
3 | "description": "Paint.NET is a free image and photo editing software for Windows.",
4 | "isPublic": true,
5 | "publisher": "dotPDN",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": true,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "PaintDotNetOfflineInstaller",
25 | "filter": "$_.Architecture -eq \"x64\" -and $_.URI -match \"winmsi\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/stealthpuppy/defaults/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Windows Enterprise Defaults",
3 | "description": "Make Windows images enterprise ready with optimisations and better defaults.",
4 | "isPublic": true,
5 | "publisher": "stealthpuppy",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "WindowsEnterpriseDefaults",
25 | "filter": "$_.Type -eq \"zip\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Google/Chrome/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Chrome",
3 | "description": "The browser built by Google. Browse with the power of Google.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "GoogleChrome",
25 | "filter": "$_.Channel -eq \"Stable\" -and $_.Architecture -eq \"x64\" -and $_.Type -eq \"msi\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/WindowsApp/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Windows App",
3 | "description": "Securely connect to Windows across Windows 365, Azure Virtual Desktop, Microsoft Dev Box, and more.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftWindowsApp",
25 | "filter": "$_.Architecture -eq \"x64\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AzureCLI/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Azure CLI",
3 | "description": "Azure CLI is a cross-platform command-line tool for managing Azure resources with interactive commands or scripts.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftAzureCLI",
25 | "filter": "$_.Architecture -eq \"x64\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/VisualC++2022x64/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Visual C++ Redistributable 14 x64",
3 | "description": "The Visual C++ Redistributable installs runtime components that are required to run applications developed with Visual C++.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "type": "VcRedist",
23 | "filter": "$_.Architecture -eq \"x64\" -and $_.Release -eq \"14\""
24 | }
25 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/VisualC++2022x86/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Visual C++ Redistributable 14 x86",
3 | "description": "The Visual C++ Redistributable installs runtime components that are required to run applications developed with Visual C++.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "type": "VcRedist",
23 | "filter": "$_.Architecture -eq \"x86\" -and $_.Release -eq \"14\""
24 | }
25 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AvdRtcService/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Remote Desktop WebRTC Redirector Service",
3 | "description": "The Remote Desktop WebRTC Redirector Service for Teams for Azure Virtual Desktop.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftWvdRtcService",
25 | "filter": "$_.Architecture -eq \"x64\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/Edge/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Edge",
3 | "description": "Microsoft Edge is a cross-platform web browser developed by Microsoft, based on the Chromium open-source project.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftEdge",
25 | "filter": "$_.Channel -eq \"Stable\" -and $_.Architecture -eq \"x64\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/Teams/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Teams",
3 | "description": "Microsoft Teams is a collaboration app that helps your team stay organized and has conversations all in one place.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftTeams",
25 | "filter": "$_.Architecture -eq \"x64\" -and $_.Release -eq \"Enterprise\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Adobe/AcrobatReader/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Acrobat Reader DC",
3 | "description": "Adobe Acrobat Reader DC is a free PDF viewer that allows you to view, print, and annotate PDF documents.",
4 | "isPublic": true,
5 | "publisher": "Adobe",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "AdobeAcrobatReaderDC",
25 | "filter": "$_.Architecture -eq \"x64\" -and $_.Language -eq \"MUI\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/OneDrive/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "OneDrive",
3 | "description": "OneDrive is a file hosting service that allows users to store files and data in the cloud.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftOneDrive",
25 | "filter": "$_.Ring -eq \"Production\" -and $_.Architecture -eq \"x64\" -and $_.Throttle -eq \"100\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Zoom/Workplace/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Zoom Workplace",
3 | "description": "Zoom Workplace is a collaboration platform that brings together chat, video, and file sharing in one place.",
4 | "isPublic": true,
5 | "publisher": "Zoom",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "Zoom",
25 | "filter": "$_.Architecture -eq \"x64\" -and $_.Type -eq \"msi\" -and $_.Platform -eq \"Desktop\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/ImageGlass/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ImageGlass",
3 | "description": "ImageGlass is a lightweight, versatile image viewer that supports a wide range of image formats and provides a user-friendly interface for viewing and managing images.",
4 | "isPublic": true,
5 | "publisher": "Duong Dieu Phap",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "ImageGlass",
25 | "filter": "$_.Architecture -eq \"x64\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AptosFont/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Aptos Font",
3 | "description": "Microsoft Aptos fonts for local installation for use in applications that do not have access to the Office Font Service.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": true,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "type": "Static",
23 | "version": "4.40",
24 | "url": "https://stavddsplbxulhzmac.blob.core.windows.net/binaries/MicrosoftAptosFonts.zip",
25 | "path": null
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/PowerToys/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "PowerToys",
3 | "description": "PowerToys is a set of utilities for power users to tune and streamline their Windows experience for greater productivity.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftPowerToys",
25 | "filter": "$_.Architecture -eq \"x64\" -and $_.InstallerType -eq \"Default\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/SQLServerManagementStudio/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "SQL Server Management Studio",
3 | "description": "SQL Server Management Studio (SSMS) is an integrated environment for managing any SQL infrastructure, from SQL Server to Azure SQL Database.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftSsms",
25 | "filter": "$_.Language -eq \"English\""
26 | }
27 | }
--------------------------------------------------------------------------------
/actions/tweaks/Install-FSLogixAppMaskingRuleset.ps1:
--------------------------------------------------------------------------------
1 | #description: Downloads and installs an FSLogix App Masking ruleset
2 | #execution mode: Combined
3 | #tags: FSLogix
4 | [System.String] $Path = "$Env:ProgramFiles\FSLogix\Apps\Rules"
5 |
6 | #region Script logic
7 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
8 | New-Item -Path "$Env:SystemRoot\Logs\ImageBuild" -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
9 |
10 | $params = @{
11 | Uri = $SecureVars.AppMaskingRuleset
12 | OutFile = "$Path\ruleset.zip"
13 | UseBasicParsing = $true
14 | ErrorAction = "Stop"
15 | }
16 | Invoke-WebRequest @params
17 |
18 | $params = @{
19 | Path = "$Path\ruleset.zip"
20 | DestinationPath = $Path
21 | Force = $true
22 | ErrorAction = "Stop"
23 | }
24 | Expand-Archive @params
25 |
26 | Remove-Item -Path "$Path\ruleset.zip" -Force -ErrorAction "SilentlyContinue"
27 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AvdMultimediaRedirection/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Multimedia Redirection Extensions",
3 | "description": "This extension enables multimedia redirection for Azure Virtual Desktop, allowing for enhanced media playback performance.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftWvdMultimediaRedirection",
25 | "filter": "$_.Architecture -eq \"x64\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/EdgeWebView2/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Edge WebView2",
3 | "description": "Microsoft Edge WebView2 is a control that allows you to embed web content in your applications using the Edge rendering engine.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftEdgeWebView2Runtime",
25 | "filter": "$_.Channel -eq \"Stable\" -and $_.Architecture -eq \"x64\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/SupportCenter/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Configuration Manager Support Center",
3 | "description": "Support Center has powerful capabilities including troubleshooting and real-time log viewing.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "type": "Static",
23 | "version": "5.2403.1209.1000",
24 | "url": "https://stavddsplbxulhzmac.blob.core.windows.net/binaries/SupportCenterInstaller.msi",
25 | "path": null
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/NETLTS/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": ".NET LTS",
3 | "description": ".NET platform that receives support and updates for an extended period, ensuring stability and security for applications built on it.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "Microsoft.NET",
25 | "filter": "$_.Installer -eq \"windowsdesktop\" -and $_.Architecture -eq \"x64\" -and $_.Channel -match \"LTS\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/ImageGlass/Install.ps1:
--------------------------------------------------------------------------------
1 | $Context.Log("Installing package: $($Context.GetAttachedBinary())")
2 | $params = @{
3 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
4 | ArgumentList = "/package `"$($Context.GetAttachedBinary())`" RUNAPPLICATION=0 ALLUSERS=1 ALLUSERS=1 /quiet"
5 | Wait = $true
6 | PassThru = $true
7 | NoNewWindow = $true
8 | ErrorAction = "Stop"
9 | }
10 | $result = Start-Process @params
11 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
12 |
13 | Start-Sleep -Seconds 5
14 | $Shortcuts = @("$Env:Public\Desktop\ImageGlass.lnk",
15 | "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\ImageGlass\ImageGlass' LICENSE.lnk",
16 | "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\ImageGlass\Uninstall ImageGlass*.lnk")
17 | Get-Item -Path $Shortcuts -ErrorAction "SilentlyContinue" | `
18 | ForEach-Object { $Context.Log("Remove file: $($_.FullName)"); Remove-Item -Path $_.FullName -Force -ErrorAction "SilentlyContinue" }
19 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/NETLTS/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\dotnet\host\fxr\$($Context.TargetVersion)\hostfxr.dll"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | if (Test-Path -Path $FilePath) {
14 | # Version on the file won't match the version of the .NET runtime, so we need to check the file's existence only.
15 | $Context.Log("File exists at: $($FilePath)")
16 | if ($Context.Versions -is [System.Array]) { return $Context.TargetVersion } else { return $true }
17 | }
18 | else {
19 | $Context.Log("File does not exist at: $($FilePath)")
20 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/FSLogixApps/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "FSLogix Apps",
3 | "description": "FSLogix Apps is a set of solutions that enhance the user experience in virtual desktop environments by providing advanced profile management, application masking, and Office 365 containerization.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftFSLogixApps",
25 | "filter": "$_.Channel -eq \"Production\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/PowerShell/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "PowerShell LTS",
3 | "description": "PowerShell is a cross-platform task automation solution made up of a command-line shell, a scripting language, and a configuration management framework.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftPowerShell",
25 | "filter": "$_.Architecture -eq \"x64\" -and $_.Type -eq \"msi\" -and $_.Release -eq \"LTS\""
26 | }
27 | }
--------------------------------------------------------------------------------
/shell-apps/Microsoft/VisualStudioCode/Definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Visual Studio Code",
3 | "description": "Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications.",
4 | "isPublic": true,
5 | "publisher": "Microsoft",
6 | "detectScript": "#detectScript",
7 | "installScript": "#installScript",
8 | "uninstallScript": "#uninstallScript",
9 | "fileUnzip": false,
10 | "versions": [
11 | {
12 | "name": "#version",
13 | "isPreview": false,
14 | "installScriptOverride": null,
15 | "file": {
16 | "sourceUrl": "#sourceUrl",
17 | "sha256": "#sha256"
18 | }
19 | }
20 | ],
21 | "source": {
22 | "import": true,
23 | "type": "Evergreen",
24 | "app": "MicrosoftVisualStudioCode",
25 | "filter": "$_.Architecture -eq \"x64\" -and $_.Channel -eq \"Stable\" -and $_.Platform -eq \"win32-x64\""
26 | }
27 | }
--------------------------------------------------------------------------------
/apps/appv/Install-ImageGlass.ps1:
--------------------------------------------------------------------------------
1 | #Requires -Modules Evergreen
2 | [System.String] $Path = "$Env:SystemDrive\Temp"
3 |
4 | Import-Module -Name "Evergreen" -Force
5 | $App = Get-EvergreenApp -Name "ImageGlass" | Where-Object { $_.Architecture -eq "x64" -and $_.Type -eq "msi" } | Select-Object -First 1
6 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
7 |
8 | $params = @{
9 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
10 | ArgumentList = "/package `"$($OutFile.FullName)`" RUNAPPLICATION=0 ALLUSERS=1 /quiet"
11 | NoNewWindow = $true
12 | Wait = $true
13 | PassThru = $true
14 | ErrorAction = "Stop"
15 | }
16 | Start-Process @params
17 |
18 | Start-Sleep -Seconds 5
19 | $Shortcuts = @("$Env:Public\Desktop\ImageGlass.lnk",
20 | "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\ImageGlass\ImageGlass' LICENSE.lnk",
21 | "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\ImageGlass\Uninstall ImageGlass*.lnk")
22 | Remove-Item -Path $Shortcuts -Force -ErrorAction "Ignore"
23 | #endregion
24 |
--------------------------------------------------------------------------------
/shell-apps/Foxit/PDFReader/Install.ps1:
--------------------------------------------------------------------------------
1 | $Options = "AUTO_UPDATE=0
2 | NOTINSTALLUPDATE=1
3 | MAKEDEFAULT=0
4 | LAUNCHCHECKDEFAULT=0
5 | VIEW_IN_BROWSER=0
6 | DESKTOP_SHORTCUT=0
7 | STARTMENU_SHORTCUT_UNINSTALL=0
8 | DISABLE_UNINSTALL_SURVEY=1
9 | CLEAN=1
10 | INTERNET_DISABLE=1"
11 | $params = @{
12 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
13 | ArgumentList = "/package `"$($Context.GetAttachedBinary())`" $($Options -replace "\s+", " ") ALLUSERS=1 /quiet"
14 | Wait = $true
15 | PassThru = $true
16 | NoNewWindow = $true
17 | ErrorAction = "Stop"
18 | }
19 | $result = Start-Process @params
20 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
21 |
22 | # Disable update tasks - assuming we're installing on a gold image or updates will be managed
23 | $Context.Log("Disable service: FoxitReaderUpdateService*")
24 | Get-Service -Name "FoxitReaderUpdateService*" -ErrorAction "SilentlyContinue" | Set-Service -StartupType "Disabled" -ErrorAction "SilentlyContinue"
25 |
--------------------------------------------------------------------------------
/apps/appv/Install-NotepadPlusPlus.ps1:
--------------------------------------------------------------------------------
1 | #Requires -Modules Evergreen
2 | [System.String] $Path = "$Env:SystemDrive\Temp"
3 |
4 | Import-Module -Name "Evergreen" -Force
5 | $App = Get-EvergreenApp -Name "NotepadPlusPlus" | Where-Object { $_.Architecture -eq "x64" -and $_.Type -eq "exe" } | Select-Object -First 1
6 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
7 |
8 | $params = @{
9 | FilePath = $OutFile.FullName
10 | ArgumentList = "/S"
11 | NoNewWindow = $true
12 | Wait = $true
13 | PassThru = $true
14 | ErrorAction = "Stop"
15 | }
16 | Start-Process @params
17 |
18 | # Disable updater
19 | $UpdaterPath = "$Env:ProgramFiles\Notepad++\updater"
20 | $RenamePath = "$Env:ProgramFiles\Notepad++\updater.disabled"
21 | if (Test-Path -Path $UpdaterPath) {
22 | if (Test-Path -Path $RenamePath) {
23 | Remove-Item -Path $RenamePath -Recurse -Force -ErrorAction "SilentlyContinue"
24 | }
25 | Rename-Item -Path $UpdaterPath -NewName "updater.disabled" -Force -ErrorAction "SilentlyContinue"
26 | }
27 | #endregion
28 |
--------------------------------------------------------------------------------
/actions/tools/Set-FSLogixStorageAccount.ps1:
--------------------------------------------------------------------------------
1 | #description: Configures authentication to an Azure storage account for FSLogix profiles, for Entra ID only environments
2 | #execution mode: Combined
3 | #tags: FSLogix, Storage Account
4 |
5 | #region Use Secure variables in Nerdio Manager to pass credentials
6 | if ($null -eq $SecureVars.HostPoolStorageAuth) {
7 | throw "Host pool storage auth not specified"
8 | }
9 | #endregion
10 |
11 | #region Configure access to the FSLogix storage account
12 | try {
13 | # Gather details from JSON file
14 | $Json = $SecureVars.HostPoolStorageAuth | ConvertFrom-Json -ErrorAction "Stop"
15 |
16 | # Store credentials to access the storage account
17 | & "$Env:SystemRoot\System32\cmdkey.exe" /add:$($Json.$HostPoolName.FileServer) /user:$($Json.$HostPoolName.User) /pass:$($Json.$HostPoolName.Secret)
18 |
19 | # Disable Windows Defender Credential Guard (required for Windows 11 22H2)
20 | reg add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v "LsaCfgFlags" /d 0 /t "REG_DWORD" /f | Out-Null
21 | }
22 | catch {
23 | throw $_
24 | }
25 | #endregion
26 |
--------------------------------------------------------------------------------
/nme/terraform/data.tf:
--------------------------------------------------------------------------------
1 | data "azuread_client_config" "current" {}
2 | data "azurerm_client_config" "current" {}
3 | data "azurerm_subscription" "current" {}
4 | data "azuread_application_published_app_ids" "well_known" {}
5 |
6 | data "azuread_service_principal" "msgraph" {
7 | client_id = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph
8 | }
9 |
10 | #The below is meant to convert the user_principal onto a valid UUID
11 | data "azuread_user" "desktop_admins" {
12 | for_each = var.desktop_admins
13 | user_principal_name = each.value
14 | }
15 |
16 | data "azuread_user" "desktop_users" {
17 | for_each = var.desktop_users
18 | user_principal_name = each.value
19 | }
20 |
21 | data "azuread_user" "helpdesk_users" {
22 | for_each = var.helpdesk_users
23 | user_principal_name = each.value
24 | }
25 |
26 | data "azuread_user" "reviewers" {
27 | for_each = var.reviewers
28 | user_principal_name = each.value
29 | }
30 |
31 | data "azuread_user" "nerdio_admins" {
32 | for_each = var.nerdio_admins
33 | user_principal_name = each.value
34 | }
35 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/OneDrive/Install.ps1:
--------------------------------------------------------------------------------
1 | $Context.Log("Run: 'reg add HKLM\Software\Microsoft\OneDrive /v AllUsersInstall /t REG_DWORD /d 1 /reg:64 /f'")
2 | reg add "HKLM\Software\Microsoft\OneDrive" /v "AllUsersInstall" /t REG_DWORD /d 1 /reg:64 /f *> $null
3 | $params = @{
4 | FilePath = $Context.GetAttachedBinary()
5 | ArgumentList = "/silent /allusers"
6 | Wait = $false
7 | PassThru = $true
8 | NoNewWindow = $true
9 | ErrorAction = "Stop"
10 | }
11 | $result = Start-Process @params
12 | do {
13 | $Context.Log("Waiting for OneDrive Setup to complete.")
14 | Start-Sleep -Seconds 5
15 | } while (Get-Process -Name "OneDriveSetup" -ErrorAction "SilentlyContinue")
16 | $Context.Log("OneDrive Setup completed.")
17 | $Context.Log("Wait a further 10 seconds for processes to complete")
18 | Start-Sleep -Seconds 10
19 | Get-Process -Name "OneDrive" -ErrorAction "SilentlyContinue" | ForEach-Object {
20 | $Context.Log("Stopped OneDrive process: $($_.Name)")
21 | Stop-Process -Name $_.Name -Force -ErrorAction "SilentlyContinue"
22 | }
23 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
24 |
--------------------------------------------------------------------------------
/apps/appv/Install-VLCMediaPlayer.ps1:
--------------------------------------------------------------------------------
1 | #Requires -Modules Evergreen
2 | [System.String] $Path = "$Env:SystemDrive\Temp"
3 |
4 | Import-Module -Name "Evergreen" -Force
5 | $App = Get-EvergreenApp -Name "VideoLanVlcPlayer" | Where-Object { $_.Architecture -eq "x64" -and $_.Type -eq "MSI" } | Select-Object -First 1
6 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
7 |
8 | $params = @{
9 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
10 | ArgumentList = "/package `"$($OutFile.FullName)`" ALLUSERS=1 /quiet"
11 | NoNewWindow = $true
12 | Wait = $true
13 | PassThru = $true
14 | ErrorAction = "Stop"
15 | }
16 | Start-Process @params
17 |
18 | Start-Sleep -Seconds 5
19 | $Shortcuts = @("$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\VideoLAN\VLC\VideoLAN website.lnk",
20 | "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\VideoLAN\VLC\Release Notes.lnk",
21 | "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\VideoLAN\VLC\Documentation.lnk",
22 | "$Env:Public\Desktop\VLC media player.lnk")
23 | Remove-Item -Path $Shortcuts -Force -ErrorAction "Ignore"
24 |
--------------------------------------------------------------------------------
/actions/core/203_MicrosoftOutlook.ps1:
--------------------------------------------------------------------------------
1 | #description: Installs the new Microsoft Outlook app
2 | #execution mode: Combined
3 | #tags: Evergreen, Microsoft, Outlook, per-machine
4 | #Requires -Modules Evergreen
5 | [System.String] $Path = "$Env:SystemDrive\Apps\Microsoft\Outlook"
6 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
7 |
8 | # Import shared functions written to disk by 000_PrepImage.ps1
9 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
10 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
11 | Write-LogFile -Message "Functions imported from: $FunctionFile"
12 |
13 | $App = [PSCustomObject]@{
14 | Version = "2.0.0"
15 | URI = "https://res.cdn.office.net/nativehost/5mttl/installer/v2/indirect/Setup.exe"
16 | }
17 | $OutlookExe = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
18 | Write-LogFile -Message "Downloaded Microsoft Outlook to: $($OutlookExe.FullName)"
19 |
20 | Write-LogFile -Message "Installing Microsoft Outlook"
21 | $params = @{
22 | FilePath = $OutlookExe.FullName
23 | ArgumentList = "--provision true --quiet --start-"
24 | }
25 | Start-ProcessWithLog @params
26 |
--------------------------------------------------------------------------------
/apps/appv/Install-Paint.NET.ps1:
--------------------------------------------------------------------------------
1 | #Requires -Modules Evergreen
2 | [System.String] $Path = "$Env:SystemDrive\Temp"
3 |
4 | Import-Module -Name "Evergreen" -Force
5 | $App = Get-EvergreenApp -Name "PaintDotNetOfflineInstaller" | `
6 | Where-Object { $_.Architecture -eq "x64" -and $_.URI -match "winmsi" } | Select-Object -First 1
7 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
8 |
9 | $params = @{
10 | Path = $OutFile.FullName
11 | DestinationPath = $Path
12 | Force = $true
13 | ErrorAction = "Stop"
14 | }
15 | Expand-Archive @params
16 |
17 | $Installer = Get-ChildItem -Path $Path -Include "paint*.msi" -Recurse
18 | $params = @{
19 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
20 | ArgumentList = "/package `"$($Installer.FullName)`" DESKTOPSHORTCUT=0 CHECKFORUPDATES=0 CHECKFORBETAS=0 /quiet"
21 | NoNewWindow = $true
22 | Wait = $true
23 | PassThru = $true
24 | ErrorAction = "Stop"
25 | }
26 | Start-Process @params
27 |
28 | Start-Sleep -Seconds 5
29 | $Shortcuts = @("$Env:Public\Desktop\Paint.NET.lnk")
30 | Remove-Item -Path $Shortcuts -Force -ErrorAction "Ignore"
31 | #endregion
32 |
--------------------------------------------------------------------------------
/import/Detect.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "check32BitOn64System": false,
4 | "detectionType": "version",
5 | "detectionValue": "5.2203.1086.1000",
6 | "keyPath": "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{69237C81-2AB9-4E98-B1AE-693DD9B070A8}",
7 | "operator": "greaterThanOrEqual",
8 | "valueName": "DisplayVersion"
9 | },
10 | {
11 | "check32BitOn64System": false,
12 | "detectionType": "version",
13 | "detectionValue": "5.2203.1086.1000",
14 | "fileOrFolderName": "ConfigMgrSupportCenterViewer.exe",
15 | "operator": "greaterThanOrEqual",
16 | "path": "C:\\Program Files (x86)\\Configuration Manager Support Center"
17 | },
18 | {
19 | "check32BitOn64System": false,
20 | "detectionType": "version",
21 | "detectionValue": "5.2203.1086.1000",
22 | "fileOrFolderName": "ConfigMgrSupportCenter.exe",
23 | "operator": "greaterThanOrEqual",
24 | "path": "C:\\Program Files (x86)\\Configuration Manager Support Center"
25 | },
26 | {
27 | "productCode": "{69237C81-2AB9-4E98-B1AE-693DD9B070A8}",
28 | "productVersion": "5.2203.1086.1000",
29 | "productVersionOperator": "greaterThanOrEqual"
30 | }
31 | ]
--------------------------------------------------------------------------------
/actions/tweaks/Set-AppLockerPolicyConfig.ps1:
--------------------------------------------------------------------------------
1 | #description: Downloads and installs a Microsoft AppLocker policy
2 | #execution mode: Combined
3 | #tags: AppLocker
4 |
5 | #region Script logic
6 | [System.String] $Path = "$Env:SystemDrive\Apps\AppLocker"
7 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
8 |
9 | if ([System.String]::IsNullOrEmpty($SecureVars.AppLockerPolicyFile)) {
10 | Write-Host "AppLocker configuration file URL not set."
11 | }
12 | else {
13 | #Download the AppLocker configuration
14 | $OutFile = "$Path\AppLocker$(Get-Date -Format "yyyyMMdd").xml"
15 | $params = @{
16 | URI = $SecureVars.AppLockerPolicyFile
17 | OutFile = $OutFile
18 | UseBasicParsing = $true
19 | ErrorAction = "Stop"
20 | }
21 | Invoke-WebRequest @params
22 |
23 | # Start the Application Identity service
24 | Start-Service -Name "AppIDSvc" -ErrorAction "SilentlyContinue"
25 | sc.exe config appidsvc start= auto
26 |
27 | # Import the AppLocker configuration
28 | $params = @{
29 | XmlPolicy = $OutFile
30 | ErrorAction = "Stop"
31 | }
32 | Set-AppLockerPolicy @params
33 | }
34 | #endregion
35 |
--------------------------------------------------------------------------------
/apps/appv/Install-FoxitPDFReader.ps1:
--------------------------------------------------------------------------------
1 | #Requires -Modules Evergreen
2 | [System.String] $Path = "$Env:SystemDrive\Temp"
3 | [System.String] $Language = "English"
4 |
5 | Import-Module -Name "Evergreen" -Force
6 | $App = Get-EvergreenApp -Name "FoxitReader" | Where-Object { $_.Language -eq $Language } | Select-Object -First 1
7 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
8 |
9 | $Options = "AUTO_UPDATE=0
10 | NOTINSTALLUPDATE=1
11 | MAKEDEFAULT=0
12 | LAUNCHCHECKDEFAULT=0
13 | VIEW_IN_BROWSER=0
14 | DESKTOP_SHORTCUT=0
15 | STARTMENU_SHORTCUT_UNINSTALL=0
16 | DISABLE_UNINSTALL_SURVEY=1
17 | CLEAN=1
18 | INTERNET_DISABLE=1"
19 | $params = @{
20 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
21 | ArgumentList = "/package `"$($OutFile.FullName)`" $($Options -replace "\s+", " ") ALLUSERS=1 /quiet"
22 | NoNewWindow = $true
23 | Wait = $true
24 | PassThru = $true
25 | ErrorAction = "Stop"
26 | }
27 | Start-Process @params
28 |
29 | # Disable update tasks - assuming we're installing on a gold image or updates will be managed
30 | Get-Service -Name "FoxitReaderUpdateService*" -ErrorAction "SilentlyContinue" | Set-Service -StartupType "Disabled" -ErrorAction "SilentlyContinue"
31 | #endregion
32 |
--------------------------------------------------------------------------------
/.devops/pipelines/validate-apps.yml:
--------------------------------------------------------------------------------
1 | # Add steps that build, run tests, deploy, and more:
2 | # https://aka.ms/yaml
3 |
4 | # trigger:
5 | # branches:
6 | # include: [ main ]
7 | # paths:
8 | # include: [ "scripts/**.ps1" ]
9 |
10 | pool: 'Azure Virtual Desktop'
11 |
12 | steps:
13 | - powershell: |
14 | Import-Module -Name "Pester" -Force -ErrorAction "Stop"
15 | $Config = New-PesterConfiguration
16 | $Config.Run.Path = "$(build.sourcesDirectory)\tests\image"
17 | $Config.Run.PassThru = $true
18 | $Config.TestResult.Enabled = $true
19 | $Config.TestResult.OutputFormat = "NUnitXml"
20 | $Config.TestResult.OutputPath = "$(build.sourcesDirectory)\TestResults.xml"
21 | $Config.Output.Verbosity = "Detailed"
22 | Invoke-Pester -Configuration $Config
23 | name: test
24 | displayName: 'Validate installed apps'
25 | workingDirectory: $(build.sourcesDirectory)
26 | errorActionPreference: continue
27 | continueOnError: true
28 |
29 | - publish: "$(build.sourcesDirectory)\\TestResults.xml"
30 | artifact: TestResults
31 | continueOnError: true
32 |
33 | - task: PublishTestResults@2
34 | inputs:
35 | testResultsFormat: "NUnit"
36 | testResultsFiles: "$(build.sourcesDirectory)\\TestResults.xml"
37 | failTaskOnFailedTests: true
38 | testRunTitle: "Publish Pester results"
39 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/FSLogixApps/Install.ps1:
--------------------------------------------------------------------------------
1 | # Configure the environment
2 | $ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
3 | $InformationPreference = [System.Management.Automation.ActionPreference]::Continue
4 | $ProgressPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue
5 | [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
6 |
7 | # Unzip the attached binary to the current directory
8 | Expand-Archive -Path $Context.GetAttachedBinary() -DestinationPath $PWD -Force
9 |
10 | # Install FSLogix Apps agent
11 | foreach ($File in "FSLogixAppsSetup.exe") {
12 | $Installers = Get-ChildItem -Path $PWD -Recurse -Include $File | Where-Object { $_.Directory -match "x64" }
13 | foreach ($Installer in $Installers) {
14 | $Context.Log("Installing Microsoft FSLogix Apps agent from: $($Installer.FullName)")
15 | $params = @{
16 | FilePath = $Installer.FullName
17 | ArgumentList = "/install /quiet /norestart"
18 | Wait = $true
19 | NoNewWindow = $true
20 | PassThru = $true
21 | ErrorAction = "Stop"
22 | }
23 | $result = Start-Process @params
24 | $Context.Log("Install complete. Return code: $($result.ExitCode)")
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/apps/configs/Redirections.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AppData\Local\CrashDumps
7 |
8 | AppData\Local\Microsoft\Terminal Server Client
9 |
10 | AppData\Local\Microsoft\Edge SxS\User Data\Default\Cache
11 |
12 | AppData\Roaming\Microsoft\Teams\media-stack
13 |
14 | AppData\Roaming\Microsoft\Teams\Service Worker
15 |
16 | AppData\Roaming\Microsoft\Teams\meeting-addin\Cache
17 |
18 |
19 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/Teams/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $PackageFamilyName = "MSTeams_8wekyb3d8bbwe"
3 |
4 | $App = Get-AppxPackage -AllUsers | Where-Object { $_.PackageFamilyName -eq $PackageFamilyName }
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if ($null -eq $App) {
8 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
9 | }
10 | else {
11 | return $true
12 | }
13 | }
14 | else {
15 | if ($null -eq $App) {
16 | $Context.Log("Microsoft Teams is not installed.")
17 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
18 | }
19 | else {
20 | $Context.Log("Found version: $($App.Version)")
21 | if ([System.Version]::Parse($App.Version) -ge [System.Version]::Parse($Context.TargetVersion)) {
22 | $Context.Log("No update required. Found '$($App.Version)' against '$($Context.TargetVersion)'.")
23 | if ($Context.Versions -is [System.Array]) { return $App.Version } else { return $true }
24 | }
25 | else {
26 | $Context.Log("Update required. Found '$($App.Version)' less than '$($Context.TargetVersion)'.")
27 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/variables/NerdioManagerVariables.json:
--------------------------------------------------------------------------------
1 | {
2 | "australiaeast": {
3 | "Language": "en-AU",
4 | "OSLanguage": "en-AU",
5 | "TimeZone": "AUS Eastern Standard Time",
6 | "AppxMode": "Block",
7 | "FSLogixAppMaskingRuleset": "https://stavdxwopw3ptwuo4o.blob.core.windows.net/configs/AppMaskingRuleset.zip",
8 | "FSLogixRedirections": "https://stavdxwopw3ptwuo4o.blob.core.windows.net/configs/Redirections.xml",
9 | "Microsoft365AppsChannel": "Current",
10 | "Microsoft365AppsConfig": "https://stavdxwopw3ptwuo4o.blob.core.windows.net/configs/Microsoft365Apps-Outlook-Shared.xml",
11 | "FoxitLanguage": "English",
12 | "FirefoxLanguage": "en-US",
13 | "FirefoxChannel": "LATEST_FIREFOX_VERSION",
14 | "CitrixWorkspaceStream": "Current",
15 | "CitrixOptimizer": "https://stavdxwopw3ptwuo4o.blob.core.windows.net/binaries/CitrixOptimizerTool.zip",
16 | "CitrixOptimizerTemplate": "https://stavdxwopw3ptwuo4o.blob.core.windows.net/configs/CitrixOptimizer-Windows11-Lite.xml",
17 | "AppLockerPolicyFile": "https://stavdxwopw3ptwuo4o.blob.core.windows.net/configs/AppLockerRules-20231114-0803-Enforce.xml",
18 | "GreenshotDefaultsIni": "https://stavdxwopw3ptwuo4o.blob.core.windows.net/configs/greenshot-defaults.ini",
19 | "AdobeAcrobatArchitecture": "x64",
20 | "AdobeAcrobatLanguage": "MUI"
21 | }
22 | }
--------------------------------------------------------------------------------
/actions/3rdparty/405_pdfforgePDFCreator.ps1:
--------------------------------------------------------------------------------
1 | #description: Installs the latest PDFForge PDFCreator
2 | #execution mode: Combined
3 | #tags: Evergreen, PDFForge, PDFCreator, PDF
4 | #Requires -Modules Evergreen
5 | [System.String] $Path = "$Env:SystemDrive\Apps\PDFForge\PDFCreator"
6 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
7 |
8 | # Import shared functions written to disk by 000_PrepImage.ps1
9 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
10 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
11 | Write-LogFile -Message "Functions imported from: $FunctionFile"
12 |
13 | Write-LogFile -Message "Query Evergreen for PDFForge PDFCreator"
14 | $App = Get-EvergreenApp -Name "PDFForgePDFCreator" | Select-Object -First 1
15 | Write-LogFile -Message "Downloading PDFForge PDFCreator version $($App.Version) to $Path"
16 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
17 |
18 | $params = @{
19 | FilePath = $OutFile.FullName
20 | ArgumentList = "/VerySilent /Lang=en /NoIcons /COMPONENTS=None"
21 | }
22 | Start-ProcessWithLog @params
23 |
24 | Start-Sleep -Seconds 5
25 | $Shortcuts = @("$Env:Public\Desktop\PDF Architect 9.lnk",
26 | "$Env:Public\Desktop\PDFCreator.lnk",
27 | "$Env:ProgramFiles\PDFCreator\PDF Architect\architect-setup.exe")
28 | Remove-Item -Path $Shortcuts -Force -ErrorAction "Ignore"
29 |
--------------------------------------------------------------------------------
/actions/tools/Install-Pester.ps1:
--------------------------------------------------------------------------------
1 | #description: Installs the Pester PowerShell module.
2 | #execution mode: Combined
3 | #tags: Pester, Testing, DevOps
4 |
5 | # Trust the PSGallery for modules
6 | [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
7 | Install-PackageProvider -Name "NuGet" -MinimumVersion "2.8.5.208"
8 | Install-PackageProvider -Name "PowerShellGet" -MinimumVersion "2.2.5"
9 | if (Get-PSRepository | Where-Object { $_.Name -eq $Repository -and $_.InstallationPolicy -ne "Trusted" }) {
10 | Set-PSRepository -Name $Repository -InstallationPolicy "Trusted"
11 | }
12 |
13 | foreach ($module in "Pester") {
14 | $installedModule = Get-Module -Name $module -ListAvailable -ErrorAction "SilentlyContinue" | `
15 | Sort-Object -Property @{ Expression = { [System.Version]$_.Version }; Descending = $true } -ErrorAction "SilentlyContinue" | `
16 | Select-Object -First 1
17 | $publishedModule = Find-Module -Name $module -ErrorAction "SilentlyContinue"
18 | if (($null -eq $installedModule) -or ([System.Version]$publishedModule.Version -gt [System.Version]$installedModule.Version)) {
19 | $params = @{
20 | Name = $module
21 | SkipPublisherCheck = $true
22 | Force = $true
23 | ErrorAction = "Stop"
24 | }
25 | Install-Module @params
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/apps/appv/Install-Greenshot.ps1:
--------------------------------------------------------------------------------
1 | #Requires -Modules Evergreen
2 | [System.String] $Path = "$Env:SystemDrive\Temp"
3 |
4 | Import-Module -Name "Evergreen" -Force
5 | $App = Get-EvergreenApp -Name "Greenshot" | Where-Object { $_.Type -eq "exe" -and $_.InstallerType -eq "Default" } | Select-Object -First 1
6 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
7 |
8 | $params = @{
9 | FilePath = $OutFile.FullName
10 | ArgumentList = "/SP- /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /TASKS= /FORCECLOSEAPPLICATIONS /LOGCLOSEAPPLICATIONS /NORESTARTAPPLICATIONS"
11 | NoNewWindow = $true
12 | Wait = $false
13 | PassThru = $true
14 | ErrorAction = "Stop"
15 | }
16 | Start-Process @params
17 |
18 | # Close Greenshot
19 | Start-Sleep -Seconds 20
20 | Get-Process -ErrorAction "SilentlyContinue" | `
21 | Where-Object { $_.Path -like "$Env:ProgramFiles\Greenshot\*" } | `
22 | Stop-Process -Force -ErrorAction "SilentlyContinue"
23 |
24 | # Remove unneeded shortcuts
25 | $Shortcuts = @("$Env:Public\Desktop\Greenshot.lnk",
26 | "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\Greenshot\License.txt.lnk",
27 | "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\Greenshot\Readme.txt.lnk",
28 | "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\Greenshot\Uninstall Greenshot.lnk")
29 | Remove-Item -Path $Shortcuts -Force -ErrorAction "Ignore"
30 | #endregion
31 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/WindowsApp/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $PackageFamilyName = "MicrosoftCorporationII.Windows365_8wekyb3d8bbwe"
3 |
4 | # Detection logic
5 | $App = Get-AppxPackage -AllUsers | Where-Object { $_.PackageFamilyName -eq $PackageFamilyName }
6 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
7 | # This should be an uninstall action
8 | if ($null -eq $App) {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | else {
12 | return $true
13 | }
14 | }
15 | else {
16 | if ($null -eq $App) {
17 | $Context.Log("Microsoft Windows App is not installed.")
18 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
19 | }
20 | else {
21 | $Context.Log("Found version: $($App.Version)")
22 | if ([System.Version]::Parse($App.Version) -ge [System.Version]::Parse($Context.TargetVersion)) {
23 | $Context.Log("No update required. Found '$($App.Version)' against '$($Context.TargetVersion)'.")
24 | if ($Context.Versions -is [System.Array]) { return $App.Version } else { return $true }
25 | }
26 | else {
27 | $Context.Log("Update required. Found '$($App.Version)' less than '$($Context.TargetVersion)'.")
28 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/actions/tweaks/Enable-RDPShortpath.ps1:
--------------------------------------------------------------------------------
1 | #description: Enable RDP Shortpath for managed and public networks - reboot required. This configuration should preferably be implemented via GPO.
2 | #execution mode: Combined
3 | #tags: RDP Shortpath, Image
4 | <#
5 | This configuration should be implemented via GPO
6 | https://learn.microsoft.com/en-us/azure/virtual-desktop/configure-rdp-shortpath
7 | #>
8 |
9 | # Add registry keys
10 | reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations" /v "fUseUdpPortRedirector" /t "REG_DWORD" /d 1 /f
11 | reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations" /v "UdpPortNumber" /t "REG_DWORD" /d 3390 /f
12 | reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations" /v "ICEControl" /t "REG_DWORD" /d 2 /f
13 |
14 | # Add windows firewall rule
15 | $params = @{
16 | DisplayName = "Remote Desktop - RDP Shortpath (UDP-In)"
17 | Action = "Allow"
18 | Description = "Inbound rule for the Remote Desktop service to allow RDP traffic. [UDP 3390]"
19 | Group = "@FirewallAPI.dll,-28752"
20 | Name = "RemoteDesktop-UserMode-In-Shortpath-UDP"
21 | PolicyStore = "PersistentStore"
22 | Profile = "Domain", "Private"
23 | Service = "TermService"
24 | Protocol = "UDP"
25 | LocalPort = 3390
26 | Program = "$Env:SystemRoot\system32\svchost.exe"
27 | Enabled = "true"
28 | ErrorAction = "Continue"
29 | }
30 | New-NetFirewallRule @params
31 |
--------------------------------------------------------------------------------
/shell-apps/stealthpuppy/defaults/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{f38de27b-799e-4c30-8a01-bfdedc622944}"
3 | [System.String] $Value = "DisplayVersion"
4 |
5 | # Detection logic
6 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
7 | # This should be an uninstall action
8 | if (Test-Path -Path $RegPath) { return $true }
9 | else {
10 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
11 | }
12 | }
13 | else {
14 | if (Test-Path -Path $RegPath) {
15 | $Context.Log("Key found: $RegPath")
16 | $RegItem = Get-ItemProperty -Path $RegPath -ErrorAction "SilentlyContinue"
17 | if ([System.Version]::Parse($RegItem.$Value) -ge [System.Version]::Parse($Context.TargetVersion)) {
18 | $Context.Log("No update required. Found '$($RegItem.$Value)' against '$($Context.TargetVersion)'.")
19 | if ($Context.Versions -is [System.Array]) { return $RegItem.$Value } else { return $true }
20 | }
21 | else {
22 | $Context.Log("Update required. Found '$($RegItem.$Value)' less than '$($Context.TargetVersion)'.")
23 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
24 | }
25 | }
26 | else {
27 | $Context.Log("Path does not exist at: $($RegPath)")
28 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/shell-apps/Obsidian/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | $Context.Log("Uninstalling Obsidian)")
18 | $params = @{
19 | FilePath = "${Env:ProgramFiles}\Obsidian\Uninstall Obsidian.exe"
20 | ArgumentList = "/allusers /S"
21 | Wait = $true
22 | PassThru = $true
23 | NoNewWindow = $true
24 | ErrorAction = "Stop"
25 | }
26 | $result = Start-Process @params
27 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Nerdio Manager scripts
2 |
3 | ## 🖥️ Scripted Actions
4 |
5 | PowerShell scripts for integration with [Scripted Actions in Nerdio Manager](https://nmehelp.getnerdio.com/hc/en-us/articles/26124327585421-Scripted-Actions-Overview).
6 |
7 | Note: this code is provided as-is, without warranty or support of any kind.
8 |
9 | These scripts can be added to your Nerdio Manager install by specifying the paths below to add individual directories:
10 |
11 | * `/actions/core` - scripts for building a Windows 10/11 pooled desktop (single session or multi-session). Can be used to build an image or run against already deployed session hosts
12 | * `/actions/3rdparty` - scripts for installing 3rd party applications
13 | * `/actions/tweaks` - scripts for implementing specific configurations and tweaks for gold images or session hosts
14 | * `/actions/optimise` - scripts to optimise the Windows image
15 |
16 | ## 🐚 Shell Apps
17 |
18 | A set of example scripts for installing applications via [Shell Apps](https://nmehelp.getnerdio.com/hc/en-us/articles/25499430784909-UAM-Shell-apps-overview-and-usage). Also see: [Automating Nerdio Manager Shell Apps, with Evergreen, Part 1](https://stealthpuppy.com/nerdio-shell-apps-p1/).
19 |
20 | ## 🛠️ Migrate
21 |
22 | A set of scripts for various functions - scripts include uninstall of third party virtual desktop agents to assist in the migration to Azure Virtual Desktop or Windows 365.
23 |
24 | ## 🧩 Apps/AppV
25 |
26 | A set of scripts for installing applications to capture via application virtualization tools such as App-V.
27 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AzureCLI/Detect.ps1:
--------------------------------------------------------------------------------
1 | [System.String] $DisplayName = "Microsoft Azure CLI"
2 |
3 | function Get-InstalledSoftware {
4 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
5 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
6 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
7 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
8 | ForEach-Object {
9 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
10 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
11 | Where-Object { $_.SystemComponent -ne 1 } | `
12 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
13 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
14 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
15 | Sort-Object -Property "Name", "Publisher"
16 | }
17 | }
18 |
19 | $App = Get-InstalledSoftware | Where-Object { $_.Name -match "$DisplayName*" }
20 | if ($App) {
21 | if ($Context.Versions -is [System.Array]) { return $_.Version } else { return $true }
22 | }
23 | else {
24 | $Context.Log("Application not installed: $DisplayName")
25 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
26 | }
27 |
--------------------------------------------------------------------------------
/nme/terraform/role-assignments.tf:
--------------------------------------------------------------------------------
1 | resource "azuread_app_role_assignment" "desktop_admins" {
2 | for_each = data.azuread_user.desktop_admins
3 | principal_object_id = each.value.object_id
4 | resource_object_id = azuread_service_principal.nerdio_manager.object_id
5 | app_role_id = "ed0cdef0-4267-4470-bfff-5e0b6944f9e4"
6 | }
7 |
8 | resource "azuread_app_role_assignment" "desktop_users" {
9 | for_each = data.azuread_user.desktop_users
10 | principal_object_id = each.value.object_id
11 | resource_object_id = azuread_service_principal.nerdio_manager.object_id
12 | app_role_id = "e856de81-1e53-486a-8668-7d564866ae39"
13 | }
14 |
15 | resource "azuread_app_role_assignment" "help_desk" {
16 | for_each = data.azuread_user.helpdesk_users
17 | principal_object_id = each.value.object_id
18 | resource_object_id = azuread_service_principal.nerdio_manager.object_id
19 | app_role_id = "a94e83da-b314-4232-b8c8-94508c5ed533"
20 | }
21 |
22 | resource "azuread_app_role_assignment" "reviewers" {
23 | for_each = data.azuread_user.reviewers
24 | principal_object_id = each.value.object_id
25 | resource_object_id = azuread_service_principal.nerdio_manager.object_id
26 | app_role_id = "0a1b7425-f55a-44a6-9caa-b9a5cc9448da"
27 | }
28 |
29 | resource "azuread_app_role_assignment" "wvd_admin" {
30 | for_each = data.azuread_user.nerdio_admins
31 | principal_object_id = each.value.object_id
32 | resource_object_id = azuread_service_principal.nerdio_manager.object_id
33 | app_role_id = "d1c2ade8-98f8-45fd-aa4a-6d06b947c66f"
34 | }
35 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/EdgeWebView2/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles(x86)}\Microsoft\EdgeWebView\Application\$($Context.TargetVersion)\msedgewebview2.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | if (Test-Path -Path $FilePath) {
14 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
15 | $Context.Log("File found: $($FileItem.FullName)")
16 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
17 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
18 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
19 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
20 | }
21 | else {
22 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
23 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
24 | }
25 | }
26 | else {
27 | $Context.Log("File does not exist at: $($FilePath)")
28 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AzureCLI/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | [System.String] $Name = "Microsoft Azure CLI"
2 |
3 | function Get-InstalledSoftware {
4 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
5 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
6 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
7 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
8 | ForEach-Object {
9 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
10 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
11 | Where-Object { $_.SystemComponent -ne 1 } | `
12 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
13 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
14 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
15 | Sort-Object -Property "Name", "Publisher"
16 | }
17 | }
18 |
19 | Get-InstalledSoftware | Where-Object { $_.Name -match "$Name*" } | ForEach-Object {
20 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
21 | $params = @{
22 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
23 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
24 | Wait = $true
25 | NoNewWindow = $true
26 | ErrorAction = "Stop"
27 | }
28 | Start-Process @params
29 | $Context.Log("Uninstall complete")
30 | }
31 |
--------------------------------------------------------------------------------
/actions/core/100_MicrosoftVcRedists.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs the supported Microsoft Visual C++ Redistributables (2012, 2013, 2022).
4 |
5 | .DESCRIPTION
6 | This script installs the Microsoft Visual C++ Redistributables for the specified versions (2012, 2013, 2022).
7 | It creates a directory to store the redistributable files and then proceeds to install them silently.
8 |
9 | .PARAMETER Path
10 | Specifies the path where the redistributable files will be stored. The default path is "$Env:SystemDrive\Apps\Microsoft\VcRedist".
11 |
12 | .EXAMPLE
13 | .\100_MicrosoftVcRedists.ps1 -Path "C:\Redist"
14 |
15 | This example installs the Microsoft Visual C++ Redistributables in the "C:\Redist" directory.
16 |
17 | .NOTES
18 | - This script requires the "VcRedist" module to be installed.
19 | - The script must be run with administrative privileges.
20 | #>
21 |
22 | #description: Installs the supported Microsoft Visual C++ Redistributables
23 | #execution mode: Combined
24 | #tags: VcRedist, Microsoft
25 | #Requires -Modules VcRedist
26 | [System.String] $Path = "$Env:SystemDrive\Apps\Microsoft\VcRedist"
27 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
28 |
29 | # Import shared functions written to disk by 000_PrepImage.ps1
30 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
31 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
32 | Write-LogFile -Message "Functions imported from: $FunctionFile"
33 |
34 | # Run tasks/install apps
35 | Write-LogFile -Message "Installing Microsoft Visual C++ Redistributables"
36 | Import-Module -Name "VcRedist" -Force
37 | Get-VcList | Save-VcRedist -Path $Path | Install-VcRedist -Silent | Out-Null
38 |
--------------------------------------------------------------------------------
/shell-apps/Zoom/Workplace/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Zoom*" } | ForEach-Object {
18 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
19 | $params = @{
20 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
21 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
22 | Wait = $true
23 | PassThru = $true
24 | NoNewWindow = $true
25 | ErrorAction = "Stop"
26 | }
27 | $result = Start-Process @params
28 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
29 | }
30 |
--------------------------------------------------------------------------------
/shell-apps/ImageGlass/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "ImageGlass*" } | ForEach-Object {
18 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
19 | $params = @{
20 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
21 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
22 | Wait = $true
23 | PassThru = $true
24 | NoNewWindow = $true
25 | ErrorAction = "Stop"
26 | }
27 | $result = Start-Process @params
28 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
29 | }
30 |
--------------------------------------------------------------------------------
/shell-apps/JGraph/draw.io/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "draw.io*" } | ForEach-Object {
18 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
19 | $params = @{
20 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
21 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
22 | Wait = $true
23 | PassThru = $true
24 | NoNewWindow = $true
25 | ErrorAction = "Stop"
26 | }
27 | $result = Start-Process @params
28 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
29 | }
30 |
--------------------------------------------------------------------------------
/shell-apps/Google/Chrome/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Google Chrome*" } | ForEach-Object {
18 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
19 | $params = @{
20 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
21 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
22 | Wait = $true
23 | PassThru = $true
24 | NoNewWindow = $true
25 | ErrorAction = "Stop"
26 | }
27 | $result = Start-Process @params
28 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
29 | }
30 |
--------------------------------------------------------------------------------
/shell-apps/ImageGlass/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\ImageGlass\ImageGlass.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.FileVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.FileVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.FileVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.FileVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.FileVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/dotPDN/Paint.NET/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Paint.NET*" } | ForEach-Object {
18 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
19 | $params = @{
20 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
21 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
22 | Wait = $true
23 | PassThru = $true
24 | NoNewWindow = $true
25 | ErrorAction = "Stop"
26 | }
27 | $result = Start-Process @params
28 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
29 | }
30 |
--------------------------------------------------------------------------------
/shell-apps/Adobe/AcrobatReader/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Adobe Acrobat*" } | ForEach-Object {
18 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
19 | $params = @{
20 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
21 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
22 | Wait = $true
23 | PassThru = $true
24 | NoNewWindow = $true
25 | ErrorAction = "Stop"
26 | }
27 | $result = Start-Process @params
28 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
29 | }
30 |
--------------------------------------------------------------------------------
/shell-apps/Foxit/PDFReader/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Foxit PDF Reader*" } | ForEach-Object {
18 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
19 | $params = @{
20 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
21 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
22 | Wait = $true
23 | PassThru = $true
24 | NoNewWindow = $true
25 | ErrorAction = "Stop"
26 | }
27 | $result = Start-Process @params
28 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
29 | }
30 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/PowerShell/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\PowerShell\7\pwsh.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.FileVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.FileVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.FileVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.FileVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.FileVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/Obsidian/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\Obsidian\Obsidian.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/JGraph/draw.io/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\draw.io\draw.io.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/Zoom/Workplace/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\Zoom\bin\Zoom.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/dotPDN/Paint.NET/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\Paint.NET\paintdotnet.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/actions/3rdparty/420_1Password.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs the 1Password Windows client.
4 |
5 | .DESCRIPTION
6 | This script installs the 1Password Windows client using the Evergreen module.
7 | It downloads the MSI installer from the specified URI and installs it silently.
8 | The installation log is saved in the specified log file.
9 |
10 | .PARAMETER Path
11 | The download path for the 1Password client. The default path is "$Env:SystemDrive\Apps\AgileBits\1Password".
12 | #>
13 |
14 | #description: Installs the 1Password Windows client
15 | #execution mode: Combined
16 | #tags: Evergreen, AgileBits, 1Password
17 | #Requires -Modules Evergreen
18 | [System.String] $Path = "$Env:SystemDrive\Apps\AgileBits\1Password"
19 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
20 |
21 | # Import shared functions written to disk by 000_PrepImage.ps1
22 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
23 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
24 | Write-LogFile -Message "Functions imported from: $FunctionFile"
25 |
26 | # Download
27 | Write-LogFile -Message "Query Evergreen for 1Password client"
28 | $App = Get-EvergreenApp -Name "1Password" | Where-Object { $_.Type -eq "msi" } | Select-Object -First 1
29 | Write-LogFile -Message "Downloading 1Password version $($App.Version) to $Path"
30 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
31 |
32 | # Install package
33 | $LogPath = (Get-LogFile).Path
34 | $LogFile = "$LogPath\1Password.log" -replace " ", ""
35 | $params = @{
36 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
37 | ArgumentList = "/package `"$($OutFile.FullName)`" /quiet /log $LogFile"
38 | }
39 | Start-ProcessWithLog @params
40 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/SupportCenter/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Configuration Manager Support Center*" } | ForEach-Object {
18 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
19 | $params = @{
20 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
21 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
22 | Wait = $true
23 | PassThru = $true
24 | NoNewWindow = $true
25 | ErrorAction = "Stop"
26 | }
27 | $result = Start-Process @params
28 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
29 | }
30 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/VisualStudioCode/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\Microsoft VS Code\Code.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/Adobe/AcrobatReader/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AvdRtcService/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Remote Desktop WebRTC Redirector Service*" } | ForEach-Object {
18 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
19 | $params = @{
20 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
21 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
22 | Wait = $true
23 | PassThru = $true
24 | NoNewWindow = $true
25 | ErrorAction = "Stop"
26 | }
27 | $result = Start-Process @params
28 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
29 | }
30 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AvdMultimediaRedirection/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\MsRDCMMRHost\MsMmrHost.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/Foxit/PDFReader/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles(x86)}\Foxit Software\Foxit PDF Reader\FoxitPDFReader.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AvdMultimediaRedirection/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Remote Desktop Multimedia Redirection Service*" } | ForEach-Object {
18 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
19 | $params = @{
20 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
21 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
22 | Wait = $true
23 | PassThru = $true
24 | NoNewWindow = $true
25 | ErrorAction = "Stop"
26 | }
27 | $result = Start-Process @params
28 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
29 | }
30 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/AvdRtcService/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\Remote Desktop WebRTC Redirector\MsRdcWebRTCSvc.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/PowerShell/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | [System.String] $Name = "PowerShell 7"
2 |
3 | function Get-InstalledSoftware {
4 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
5 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
6 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
7 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
8 | ForEach-Object {
9 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
10 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
11 | Where-Object { $_.SystemComponent -ne 1 } | `
12 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
13 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
14 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
15 | Sort-Object -Property "Name", "Publisher"
16 | }
17 | }
18 |
19 | Get-InstalledSoftware | Where-Object { $_.Name -match "$Name*" } | ForEach-Object {
20 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
21 | $params = @{
22 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
23 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
24 | Wait = $true
25 | PassThru = $true
26 | NoNewWindow = $true
27 | ErrorAction = "Stop"
28 | }
29 | $result = Start-Process @params
30 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
31 | }
32 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/SupportCenter/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles(x86)}\Configuration Manager Support Center\ConfigMgrSupportCenterViewer.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/PowerToys/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\PowerToys\PowerToys.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return ($FileInfo.ProductVersion.Substring(0, $FileInfo.ProductVersion.LastIndexOf('.'))) } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/SQLServerManagementStudio/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles(x86)}\Microsoft SQL Server Management Studio 20\Common7\IDE\Ssms.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $Context.Log("File product version: $($FileInfo.ProductVersion)")
19 | $Context.Log("Target Shell App version: $($Context.TargetVersion)")
20 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
21 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
22 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
23 | }
24 | else {
25 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
26 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
27 | }
28 | }
29 | else {
30 | $Context.Log("File does not exist at: $($FilePath)")
31 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/actions/optimise/Remove-UScheduleKeys.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .DESCRIPTION
3 | This script deletes registry keys associated with the Windows Update Orchestrator's
4 | UScheduler for specific applications such as DevHomeUpdate, OutlookUpdate, and MS_Outlook.
5 |
6 | Run script at initial session host deployment
7 | #>
8 | reg delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate" /f *>$null
9 | reg delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate" /f *>$null
10 | reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate" /f *>$null
11 | reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate" /f *>$null
12 | reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\MS_Outlook" /f *>$null
13 |
14 | # Testing store app updates
15 | # reg delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\LXP" /f *>$null
16 | # reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\LXP" /f *>$null
17 | # reg delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\IA" /f *>$null
18 | # reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\IA" /f *>$null
19 | # reg delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\CrossDeviceUpdate" /f *>$null
20 | # reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\CrossDeviceUpdate" /f *>$null
21 | # reg delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\TFLUpdate" /f *>$null
22 | # reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\TFLUpdate" /f *>$null
23 |
--------------------------------------------------------------------------------
/shell-apps/Audacity/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | $Context.Log("Uninstalling Audacity)")
18 | $params = @{
19 | FilePath = "${Env:ProgramFiles}\Audacity\unins000.exe"
20 | ArgumentList = "/VERYSILENT"
21 | Wait = $true
22 | PassThru = $true
23 | NoNewWindow = $true
24 | ErrorAction = "Stop"
25 | }
26 | $result = Start-Process @params
27 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
28 |
29 | $Shortcuts = @("$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\Audacity.lnk")
30 | Get-Item -Path $Shortcuts -ErrorAction "SilentlyContinue" | `
31 | ForEach-Object { $Context.Log("Remove file: $($_.FullName)"); Remove-Item -Path $_.FullName -Force -ErrorAction "SilentlyContinue" }
32 |
--------------------------------------------------------------------------------
/actions/core/012_WindowsUpdate.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs all available Windows updates with PSWindowsUpdate.
4 |
5 | .DESCRIPTION
6 | This script installs all available Windows updates using the PSWindowsUpdate module.
7 | It first deletes the policy setting created by MDT and then proceeds to install the updates.
8 | The script uses the Install-WindowsUpdate cmdlet with the necessary parameters to accept all updates,
9 | include Microsoft updates, and ignore reboot requirements.
10 |
11 | .OUTPUTS
12 | The script outputs the Title and Size properties of the installed updates.
13 | #>
14 |
15 | #description: Installs all available Windows updates with PSWindowsUpdate
16 | #execution mode: Combined
17 | #tags: Update, Image
18 | #Requires -Modules PSWindowsUpdate
19 |
20 | # Import shared functions written to disk by 000_PrepImage.ps1
21 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
22 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
23 | Write-LogFile -Message "Functions imported from: $FunctionFile"
24 |
25 | # Delete the policy setting created by MDT
26 | Start-ProcessWithLog -FilePath "$Env:SystemRoot\System32\reg.exe" -ArgumentList "delete HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU /f"
27 |
28 | # Install updates
29 | Write-LogFile -Message "Installing all available Windows updates with PSWindowsUpdate"
30 | Import-Module -Name "PSWindowsUpdate"
31 | $params = @{
32 | Install = $true
33 | Download = $true
34 | AcceptAll = $true
35 | MicrosoftUpdate = $true
36 | IgnoreReboot = $true
37 | IgnoreRebootRequired = $true
38 | IgnoreUserInput = $true
39 | }
40 | Install-WindowsUpdate @params | Select-Object -Property "Title", "Size" | ForEach-Object {
41 | Write-LogFile -Message "Installed update: $($_.Title)"
42 | }
43 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/PowerToys/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "PowerToys*" } | ForEach-Object {
18 | if ($_.UninstallString -match '"([^"]+)"') {
19 | $Context.Log("Uninstall with: $($Matches[1])")
20 | $params = @{
21 | FilePath = $Matches[1]
22 | ArgumentList = "/uninstall /quiet /norestart"
23 | Wait = $true
24 | PassThru = $true
25 | NoNewWindow = $true
26 | ErrorAction = "Stop"
27 | }
28 | $result = Start-Process @params
29 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
30 | }
31 | else {
32 | $Context.Log("Failed to parse UninstallString")
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/FSLogixApps/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\FSLogix\Apps\frxsvc.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | if (Test-Path -Path $FilePath) {
14 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
15 | $Context.Log("File found: $($FileItem.FullName)")
16 |
17 | # FSLogix version will be in the form of "25.06", so we need construct the version numbers to compare
18 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
19 | $ProductVersion = [System.Version]::Parse("$($FileInfo.ProductVersion).0")
20 | $ContextVersion = [System.Version]::Parse("$($Context.TargetVersion).0")
21 | $CompareContextVersion = [System.Version]::Parse("3.$($ContextVersion.Major).0")
22 |
23 | if ($ProductVersion -ge $CompareContextVersion) {
24 | $Context.Log("No update required. Found '$($ProductVersion.ToString())' against '$($CompareContextVersion.ToString())'.")
25 | if ($Context.Versions -is [System.Array]) { return $Context.TargetVersion } else { return $true }
26 | }
27 | else {
28 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
29 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
30 | }
31 | }
32 | else {
33 | $Context.Log("File does not exist at: $($FilePath)")
34 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/FSLogixApps/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Microsoft FSLogix Apps*" } | ForEach-Object {
18 | if ($_.UninstallString -match '"([^"]+)"') {
19 | $Context.Log("Uninstall with: $($Matches[1])")
20 | $params = @{
21 | FilePath = $Matches[1]
22 | ArgumentList = "/uninstall /quiet /norestart"
23 | Wait = $true
24 | PassThru = $true
25 | NoNewWindow = $true
26 | ErrorAction = "Stop"
27 | }
28 | $result = Start-Process @params
29 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
30 | }
31 | else {
32 | $Context.Log("Failed to parse UninstallString")
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/NETLTS/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Microsoft Windows Desktop Runtime*" } | ForEach-Object {
18 | if ($_.UninstallString -match '"([^"]+)"') {
19 | $Context.Log("Uninstall with: $($Matches[1])")
20 | $params = @{
21 | FilePath = $Matches[1]
22 | ArgumentList = "/uninstall /quiet /norestart"
23 | Wait = $true
24 | PassThru = $true
25 | NoNewWindow = $true
26 | ErrorAction = "Stop"
27 | }
28 | $result = Start-Process @params
29 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
30 | }
31 | else {
32 | $Context.Log("Failed to parse UninstallString")
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/OneDrive/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Microsoft OneDrive*" } | ForEach-Object {
18 | if ($_.UninstallString -match '"([^"]+)"') {
19 | $Context.Log("Uninstall with: $($Matches[1])")
20 | $params = @{
21 | FilePath = $Matches[1]
22 | ArgumentList = "/uninstall /allusers /quiet /norestart"
23 | Wait = $true
24 | PassThru = $true
25 | NoNewWindow = $true
26 | ErrorAction = "Stop"
27 | }
28 | $result = Start-Process @params
29 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
30 | }
31 | else {
32 | $Context.Log("Failed to parse UninstallString")
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/shell-apps/Audacity/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\Audacity\Audacity.exe"
3 |
4 | # Detection logic
5 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
6 | # This should be an uninstall action
7 | if (Test-Path -Path $FilePath) { return $true }
8 | else {
9 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
10 | }
11 | }
12 | else {
13 | # This should be an install action, so we need to check the file version
14 | if (Test-Path -Path $FilePath) {
15 | $Context.Log("File found: $FilePath")
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
18 | $FileVersion = [System.Version]::Parse(($FileInfo.ProductVersion -replace ",", "."))
19 | $FileVersionJoin = $FileVersion.Major, $FileVersion.Minor, $FileVersion.Build -join "."
20 | $Context.Log("Found version: $FileVersionJoin")
21 | $Context.Log("Compare to: $($Context.TargetVersion)")
22 | if ([System.Version]::Parse($FileVersionJoin) -ge [System.Version]::Parse($Context.TargetVersion)) {
23 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
24 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
25 | }
26 | else {
27 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
28 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
29 | }
30 | }
31 | else {
32 | $Context.Log("File does not exist at: $($FilePath)")
33 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
34 | }
35 | }
--------------------------------------------------------------------------------
/shell-apps/Google/Chrome/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles}\Google\Chrome\Application\chrome.exe"
3 | [System.String] $PrefsPath = "${Env:ProgramFiles}\Google\Chrome\Application\initial_preferences"
4 |
5 | # Detection logic
6 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
7 | # This should be an uninstall action
8 | if (Test-Path -Path $FilePath) { return $true }
9 | else {
10 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
11 | }
12 | }
13 | else {
14 | if (Test-Path -Path $FilePath) {
15 | if (Test-Path -Path $PrefsPath) {
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $Context.Log("File found: $($FileItem.FullName)")
18 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
19 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
20 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
21 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
22 | }
23 | else {
24 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
25 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
26 | }
27 | }
28 | else {
29 | $Context.Log("File does not exist at: $($PrefsPath)")
30 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
31 | }
32 | }
33 | else {
34 | $Context.Log("File does not exist at: $($FilePath)")
35 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/Edge/Detect.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $FilePath = "${Env:ProgramFiles(x86)}\Microsoft\Edge\Application\msedge.exe"
3 | [System.String] $PrefsPath = "${Env:ProgramFiles(x86)}\Microsoft\Edge\Application\initial_preferences"
4 |
5 | # Detection logic
6 | if ([System.String]::IsNullOrEmpty($Context.TargetVersion)) {
7 | # This should be an uninstall action
8 | if (Test-Path -Path $FilePath) { return $true }
9 | else {
10 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
11 | }
12 | }
13 | else {
14 | if (Test-Path -Path $FilePath) {
15 | if (Test-Path -Path $PrefsPath) {
16 | $FileItem = Get-ChildItem -Path $FilePath -ErrorAction "SilentlyContinue"
17 | $Context.Log("File found: $($FileItem.FullName)")
18 | $FileInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($FileItem.FullName)
19 | if ([System.Version]::Parse($FileInfo.ProductVersion) -ge [System.Version]::Parse($Context.TargetVersion)) {
20 | $Context.Log("No update required. Found '$($FileInfo.ProductVersion)' against '$($Context.TargetVersion)'.")
21 | if ($Context.Versions -is [System.Array]) { return $FileInfo.ProductVersion } else { return $true }
22 | }
23 | else {
24 | $Context.Log("Update required. Found '$($FileInfo.ProductVersion)' less than '$($Context.TargetVersion)'.")
25 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
26 | }
27 | }
28 | else {
29 | $Context.Log("File does not exist at: $($PrefsPath)")
30 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
31 | }
32 | }
33 | else {
34 | $Context.Log("File does not exist at: $($FilePath)")
35 | if ($Context.Versions -is [System.Array]) { return $null } else { return $false }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/actions/core/011_SupportFunctions.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs PowerShell modules required for building AVD images (Evergreen, VcRedist, PSWindowsUpdate, etc.)
4 |
5 | .DESCRIPTION
6 | This script installs the necessary PowerShell modules for building AVD (Azure Virtual Desktop) images.
7 | It ensures that the PSGallery is trusted, installs the required package providers,
8 | and then installs the Evergreen, VcRedist, and PSWindowsUpdate modules if they are not already installed or if a newer version is available.
9 | #>
10 |
11 | #description: Installs PowerShell modules required for building AVD images (Evergreen, VcRedist, PSWindowsUpdate, etc.)
12 | #execution mode: Combined
13 | #tags: Evergreen, VcRedist, Image
14 |
15 | # Import shared functions written to disk by 000_PrepImage.ps1
16 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
17 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
18 | Write-LogFile -Message "Functions imported from: $FunctionFile"
19 |
20 | # Trust the PSGallery for modules
21 | Write-LogFile -Message "Install-PackageProvider: PowerShellGet" -LogLevel 1
22 | [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
23 | Install-PackageProvider -Name "PowerShellGet" -MinimumVersion "2.2.5" -Force
24 | Write-LogFile -Message "Set-PSRepository: PSGallery" -LogLevel 1
25 | Set-PSRepository -Name "PSGallery" -InstallationPolicy "Trusted"
26 |
27 | # Evergreen: https://eucpilots.com/evergreen-docs/
28 | # VcRedist: https://vcredist.com/
29 | # PSWindowsUpdate: https://www.powershellgallery.com/packages/PSWindowsUpdate
30 | Set-PSRepository -Name "PSGallery" -InstallationPolicy "Trusted"
31 | Write-LogFile -Message "Install-Module: PSWindowsUpdate" -LogLevel 1
32 | Install-Module -Name "PSWindowsUpdate" -Force
33 | Write-LogFile -Message "Install-Module: VcRedist" -LogLevel 1
34 | Install-Module -Name "VcRedist" -Force
35 | Write-LogFile -Message "Install-Module: Evergreen" -LogLevel 1
36 | Install-Module -Name "Evergreen" -Force
37 | Update-Evergreen -Force
38 |
--------------------------------------------------------------------------------
/nme/terraform/vnet.tf:
--------------------------------------------------------------------------------
1 | resource "azurerm_virtual_network" "nerdio" {
2 | name = "${lower(var.base_name)}-vnet"
3 | location = local.resource_group_location
4 | resource_group_name = local.resource_group_name
5 |
6 | address_space = var.vnet_address_space
7 |
8 | tags = var.tags
9 | }
10 |
11 | resource "azurerm_subnet" "private_endpoints" {
12 | name = "private-endpoints"
13 | virtual_network_name = azurerm_virtual_network.nerdio.name
14 | resource_group_name = azurerm_virtual_network.nerdio.resource_group_name
15 | address_prefixes = [cidrsubnet(azurerm_virtual_network.nerdio.address_space[0], 1, 0)]
16 |
17 | #private_endpoint_network_policies_enabled = true
18 | }
19 |
20 | resource "azurerm_subnet" "appsvc" {
21 | name = "appsvc"
22 | virtual_network_name = azurerm_virtual_network.nerdio.name
23 | resource_group_name = azurerm_virtual_network.nerdio.resource_group_name
24 | address_prefixes = [cidrsubnet(azurerm_virtual_network.nerdio.address_space[0], 1, 1)]
25 |
26 | delegation {
27 | name = "delegation"
28 |
29 | service_delegation {
30 | name = "Microsoft.Web/serverFarms"
31 | actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
32 | }
33 | }
34 | }
35 |
36 | resource "azurerm_network_security_group" "nerdio" {
37 | name = "${lower(var.base_name)}-nsg"
38 | location = local.resource_group_location
39 | resource_group_name = local.resource_group_name
40 |
41 | tags = var.tags
42 | }
43 |
44 | resource "azurerm_subnet_network_security_group_association" "private_endpoints" {
45 | subnet_id = azurerm_subnet.private_endpoints.id
46 | network_security_group_id = azurerm_network_security_group.nerdio.id
47 | }
48 |
49 | resource "azurerm_subnet_network_security_group_association" "appsvc" {
50 | subnet_id = azurerm_subnet.appsvc.id
51 | network_security_group_id = azurerm_network_security_group.nerdio.id
52 | }
53 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/VisualC++2022x64/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Microsoft Visual C\+\+ 14 Redistributable (x64)*" } | ForEach-Object {
18 | if ($_.UninstallString -match '"([^"]+)"') {
19 | $Context.Log("Uninstall with: $($Matches[1])")
20 | $params = @{
21 | FilePath = $Matches[1]
22 | ArgumentList = "/uninstall /quiet /norestart"
23 | Wait = $true
24 | PassThru = $true
25 | NoNewWindow = $true
26 | ErrorAction = "Stop"
27 | }
28 | $result = Start-Process @params
29 | $Context.Log("Remove file: ${Env:SystemRoot}\System32\vcruntime140.dll")
30 | Remove-Item -Path "${Env:SystemRoot}\System32\vcruntime140.dll" -ErrorAction "SilentlyContinue"
31 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
32 | }
33 | else {
34 | $Context.Log("Failed to parse UninstallString")
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/VisualC++2022x86/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Microsoft Visual C\+\+ 14 Redistributable (x86)*" } | ForEach-Object {
18 | if ($_.UninstallString -match '"([^"]+)"') {
19 | $Context.Log("Uninstall with: $($Matches[1])")
20 | $params = @{
21 | FilePath = $Matches[1]
22 | ArgumentList = "/uninstall /quiet /norestart"
23 | Wait = $true
24 | PassThru = $true
25 | NoNewWindow = $true
26 | ErrorAction = "Stop"
27 | }
28 | $result = Start-Process @params
29 | $Context.Log("Remove file: ${Env:SystemRoot}\SysWOW64\vcruntime140.dll")
30 | Remove-Item -Path "${Env:SystemRoot}\SysWOW64\vcruntime140.dll" -ErrorAction "SilentlyContinue"
31 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
32 | }
33 | else {
34 | $Context.Log("Failed to parse UninstallString")
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/actions/core/213_MicrosoftWindowsApp.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs the latest Microsoft Windows App.
4 |
5 | .DESCRIPTION
6 | This script installs the latest version of the Microsoft Windows App.
7 | It uses the Evergreen module to retrieve the appropriate version of the client and installs it silently.
8 |
9 | .PARAMETER Path
10 | The path where the Microsoft Windows App will be downloaded.
11 | The default path is "$Env:SystemDrive\Apps\Microsoft\Avd".
12 |
13 | .NOTES
14 | - This script requires the Evergreen module to be installed.
15 | - The script creates a log file in "$Env:SystemRoot\Logs\ImageBuild" to track the installation progress.
16 | - The script only installs the x64 version of the client from the "Public" channel.
17 | - The installation is performed silently without creating a desktop shortcut.
18 | #>
19 |
20 | #description: Installs the latest Microsoft Windows App
21 | #execution mode: Combined
22 | #tags: Evergreen, Microsoft, Remote Desktop
23 | #Requires -Modules Evergreen
24 | [System.String] $Path = "$Env:SystemDrive\Apps\Microsoft\Avd"
25 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
26 |
27 | # Import shared functions written to disk by 000_PrepImage.ps1
28 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
29 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
30 | Write-LogFile -Message "Functions imported from: $FunctionFile"
31 |
32 | #region Script logic
33 |
34 | $App = Get-EvergreenApp -Name "MicrosoftWindowsApp" | `
35 | Where-Object { $_.Architecture -eq "x64" } | Select-Object -First 1
36 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
37 | Write-LogFile -Message "Microsoft Windows App $($App.Version) downloaded to: $($OutFile.FullName)"
38 |
39 | Write-LogFile -Message "Starting Microsoft Windows App installation from: $($OutFile.FullName)"
40 | $params = @{
41 | PackagePath = $OutFile.FullName
42 | Online = $true
43 | SkipLicense = $true
44 | ErrorAction = "Stop"
45 | }
46 | Add-AppxProvisionedPackage @params
47 | #endregion
48 |
--------------------------------------------------------------------------------
/actions/3rdparty/402_ZoomMeetings.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs the latest Zoom Meetings VDI client.
4 |
5 | .DESCRIPTION
6 | This script installs the latest Zoom Meetings VDI client by downloading it using the Evergreen module and installing it silently using msiexec.exe.
7 |
8 | .PARAMETER Path
9 | The path where the Zoom Meetings VDI client will be downloaded. The default path is "$Env:SystemDrive\Apps\Zoom\Meetings".
10 |
11 | .NOTES
12 | - This script requires the Evergreen module to be installed.
13 | - The script creates a log file at "$Env:SystemRoot\Logs\ImageBuild\ZoomMeetings.log" to track the installation progress.
14 | - The script uses the Start-Process cmdlet to execute msiexec.exe with the necessary arguments for silent installation.
15 | #>
16 |
17 | #description: Installs the latest Zoom Meetings VDI client
18 | #execution mode: Combined
19 | #tags: Evergreen, Zoom
20 | #Requires -Modules Evergreen
21 | [System.String] $Path = "$Env:SystemDrive\Apps\Zoom\Meetings"
22 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
23 |
24 | # Import shared functions written to disk by 000_PrepImage.ps1
25 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
26 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
27 | Write-LogFile -Message "Functions imported from: $FunctionFile"
28 |
29 | # Download Zoom
30 | Write-LogFile -Message "Downloading Zoom Meetings VDI client"
31 | $App = Get-EvergreenApp -Name "ZoomVDI" | Where-Object { $_.Platform -eq "VDIClient" -and $_.Architecture -eq "x64" } | Select-Object -First 1
32 | Write-LogFile -Message "Downloading Zoom Meetings VDI client version $($App.Version) to $Path"
33 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
34 |
35 | $LogPath = (Get-LogFile).Path
36 | $LogFile = "$LogPath\ZoomMeetings$($App.Version).log" -replace " ", ""
37 | $params = @{
38 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
39 | ArgumentList = "/package `"$($OutFile.FullName)`" zSilentStart=false zNoDesktopShortCut=true ALLUSERS=1 /quiet /log $LogFile"
40 | }
41 | Start-ProcessWithLog @params
42 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/Teams/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | # Variables
2 | [System.String] $PackageFamilyName = "MSTeams_8wekyb3d8bbwe"
3 |
4 | function Get-InstalledSoftware {
5 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
6 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
7 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
8 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
9 | ForEach-Object {
10 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
11 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
12 | Where-Object { $_.SystemComponent -ne 1 } | `
13 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
14 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
15 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
16 | Sort-Object -Property "Name", "Publisher"
17 | }
18 | }
19 |
20 | Get-InstalledSoftware | Where-Object { $_.Name -match "Microsoft Teams Meeting Add-in*" } | ForEach-Object {
21 | $Context.Log("Uninstalling Windows Installer: $($_.PSChildName)")
22 | $params = @{
23 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
24 | ArgumentList = "/uninstall `"$($_.PSChildName)`" /quiet /norestart"
25 | Wait = $true
26 | PassThru = $true
27 | NoNewWindow = $true
28 | ErrorAction = "Stop"
29 | }
30 | $result = Start-Process @params
31 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
32 | }
33 |
34 | Get-AppxPackage -AllUsers | Where-Object { $_.PackageFamilyName -eq $PackageFamilyName } | ForEach-Object {
35 | $Context.Log("Removing existing AppX package: $($_.Name)")
36 | $_ | Remove-AppxPackage -AllUsers -ErrorAction "Stop"
37 | }
38 | Start-Sleep -Seconds 10
39 | $Context.Log("Uninstall complete")
40 |
--------------------------------------------------------------------------------
/actions/core/103_MicrosoftNET.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs the Microsoft .NET Desktop LTS and Current Runtimes.
4 |
5 | .DESCRIPTION
6 | This script installs the Microsoft .NET Desktop LTS (Long-Term Support) and Current Runtimes.
7 | It uses the Evergreen module to download the appropriate installer and installs it silently with the specified command-line arguments.
8 |
9 | .PARAMETER Path
10 | The path where the Microsoft .NET runtime will be downloaded. The default path is "$Env:SystemDrive\Apps\Microsoft\NET".
11 |
12 | .EXAMPLE
13 | .\103_MicrosoftNET.ps1
14 | Installs the Microsoft .NET Desktop LTS and Current Runtimes using the default installation path.
15 |
16 | .NOTES
17 | - This script requires the Evergreen module to be installed.
18 | - The script creates a log file at "$Env:SystemRoot\Logs\ImageBuild\Microsoft.NET.log" to capture installation logs.
19 | #>
20 |
21 | #description: Installs the Microsoft .NET Desktop LTS
22 | #execution mode: Combined
23 | #tags: Evergreen, Microsoft, .NET
24 | #Requires -Modules Evergreen
25 | [System.String] $Path = "$Env:SystemDrive\Apps\Microsoft\NET"
26 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
27 |
28 | # Import shared functions written to disk by 000_PrepImage.ps1
29 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
30 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
31 | Write-LogFile -Message "Functions imported from: $FunctionFile"
32 |
33 | #region Script logic
34 | # Download
35 |
36 | $App = Get-EvergreenApp -Name "Microsoft.NET" | `
37 | Where-Object { $_.Installer -eq "windowsdesktop" -and $_.Architecture -eq "x64" -and $_.Channel -match "LTS" }
38 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
39 |
40 | $LogPath = (Get-LogFile).Path
41 | foreach ($File in $OutFile) {
42 | $LogFile = "$LogPath\Microsoft.NET.log" -replace " ", ""
43 | Write-LogFile -Message "Installing Microsoft .NET Desktop LTS"
44 | $params = @{
45 | FilePath = $File.FullName
46 | ArgumentList = "/install /quiet /norestart /log $LogFile"
47 | }
48 | Start-ProcessWithLog @params
49 | }
50 | #endregion
51 |
--------------------------------------------------------------------------------
/actions/3rdparty/411_draw.io.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs the latest version of draw.io.
4 |
5 | .DESCRIPTION
6 | This script installs the latest version of draw.io using the Evergreen module.
7 | It creates a directory for draw.io, imports the Evergreen module, retrieves the latest version of the diagrams.net MSI package,
8 | saves it to the draw.io directory, and then installs draw.io silently using msiexec.exe.
9 |
10 | .PARAMETER Path
11 | The path where draw.io will be downloaded. The default path is "$Env:SystemDrive\Apps\draw.io".
12 |
13 | .NOTES
14 | - This script requires the Evergreen module to be installed.
15 | - The script will create a log file in "$Env:SystemRoot\Logs\ImageBuild" to track the installation progress.
16 | - The script will remove the draw.io shortcut from the desktop after installation.
17 | #>
18 |
19 | #description: Installs the latest draw.io
20 | #execution mode: Combined
21 | #tags: Evergreen, draw.io
22 | #Requires -Modules Evergreen
23 | [System.String] $Path = "$Env:SystemDrive\Apps\drawio"
24 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
25 |
26 | # Import shared functions written to disk by 000_PrepImage.ps1
27 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
28 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
29 | Write-LogFile -Message "Functions imported from: $FunctionFile"
30 |
31 |
32 | Write-LogFile -Message "Query Evergreen for JGraphDrawIO MSI"
33 | $App = Get-EvergreenApp -Name "JGraphDrawIO" | Where-Object { $_.Type -eq "msi" } | Select-Object -First 1
34 | Write-LogFile -Message "Downloading draw.io version $($App.Version) to $Path"
35 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
36 |
37 | $LogPath = (Get-LogFile).Path
38 | $LogFile = "$LogPath\drawio$($App.Version).log" -replace " ", ""
39 | $params = @{
40 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
41 | ArgumentList = "/package `"$($OutFile.FullName)`" ALLUSERS=1 /quiet /log $LogFile"
42 | }
43 | Start-ProcessWithLog @params
44 |
45 | Start-Sleep -Seconds 5
46 | $Shortcuts = @("$Env:Public\Desktop\draw.io.lnk")
47 | Remove-Item -Path $Shortcuts -Force -ErrorAction "Ignore"
48 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/VisualStudioCode/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Microsoft Visual Studio Code*" } | ForEach-Object {
18 | if ($_.UninstallString -match '"([^"]+)"') {
19 | $Context.Log("Uninstall with: $($Matches[1])")
20 | $params = @{
21 | FilePath = $Matches[1]
22 | ArgumentList = "/VERYSILENT /NORESTART"
23 | Wait = $true
24 | PassThru = $true
25 | NoNewWindow = $true
26 | ErrorAction = "Stop"
27 | }
28 | $result = Start-Process @params
29 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
30 | }
31 | else {
32 | $Context.Log("Failed to parse UninstallString")
33 | }
34 | }
35 |
36 | # Remove shortcuts
37 | $Shortcuts = @("$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code\Visual Studio Code.lnk")
38 | Get-Item -Path $Shortcuts -ErrorAction "SilentlyContinue" | `
39 | ForEach-Object { $Context.Log("Remove file: $($_.FullName)"); Remove-Item -Path $_.FullName -Force -ErrorAction "SilentlyContinue" }
40 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/SQLServerManagementStudio/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Where-Object { $_.SystemComponent -ne 1 } | `
10 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
11 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
12 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
13 | Sort-Object -Property "Name", "Publisher"
14 | }
15 | }
16 |
17 | Get-InstalledSoftware | Where-Object { $_.Name -match "Microsoft SQL Server Management Studio*" } | ForEach-Object {
18 | if ($_.UninstallString -match '"([^"]+)"') {
19 | $Context.Log("Uninstall with: $($Matches[1])")
20 | $params = @{
21 | FilePath = $Matches[1]
22 | ArgumentList = "/uninstall /allusers /quiet /norestart"
23 | Wait = $true
24 | PassThru = $true
25 | NoNewWindow = $true
26 | ErrorAction = "Stop"
27 | }
28 | $result = Start-Process @params
29 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
30 | }
31 | else {
32 | $Context.Log("Failed to parse UninstallString")
33 | }
34 | }
35 |
36 | # Remove shortcuts
37 | $Shortcuts = @("$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft SQL Server Tools 20")
38 | Get-Item -Path $Shortcuts -ErrorAction "SilentlyContinue" | `
39 | ForEach-Object { $Context.Log("Remove file: $($_.FullName)"); Remove-Item -Path $_.FullName -Force -ErrorAction "SilentlyContinue" }
40 |
--------------------------------------------------------------------------------
/actions/core/214_MicrosoftAzureCLI.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs the latest Microsoft Azure CLI.
4 |
5 | .DESCRIPTION
6 | This script installs the latest version of Microsoft Azure CLI on the local machine.
7 | It uses the Evergreen module to download and install the MSI package for Microsoft Azure CLI.
8 | The installation is performed silently without any user interaction.
9 |
10 | .PARAMETER Path
11 | Specifies the download path for Microsoft Azure CLI. The default path is "$Env:SystemDrive\Apps\Microsoft\AzureCli".
12 |
13 | .NOTES
14 | - This script requires the Evergreen module to be installed.
15 | - The script creates a log file in "$Env:SystemRoot\Logs\ImageBuild" directory to track the installation progress and any errors that occur during the installation.
16 | - The script uses the Start-Process cmdlet to execute the MSI package installation silently.
17 | #>
18 |
19 | #description: Installs the latest Microsoft Azure CLI
20 | #execution mode: Combined
21 | #tags: Evergreen, Microsoft, Azure
22 | #Requires -Modules Evergreen
23 | [System.String] $Path = "$Env:SystemDrive\Apps\Microsoft\AzureCli"
24 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
25 |
26 | # Import shared functions written to disk by 000_PrepImage.ps1
27 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
28 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
29 | Write-LogFile -Message "Functions imported from: $FunctionFile"
30 |
31 | #region Script logic
32 |
33 | $App = Get-EvergreenApp -Name "MicrosoftAzureCLI" | `
34 | Where-Object { $_.Type -eq "msi" } | Select-Object -First 1
35 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
36 | Write-LogFile -Message "Microsoft Azure CLI $($App.Version) downloaded to: $($OutFile.FullName)"
37 |
38 | $LogPath = (Get-LogFile).Path
39 | $LogFile = "$LogPath\MicrosoftAvdCli$($App.Version).log" -replace " ", ""
40 | Write-LogFile -Message "Starting Microsoft Azure CLI installation from: $($OutFile.FullName)"
41 | $params = @{
42 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
43 | ArgumentList = "/package `"$($OutFile.FullName)`" /quiet /norestart ALLUSERS=1 /log $LogFile"
44 | }
45 | Start-ProcessWithLog @params
46 | #endregion
47 |
--------------------------------------------------------------------------------
/actions/3rdparty/408_RemoteDesktopAnalyzer.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Downloads the Remote Display Analyzer and Connection Experience Indicator to 'C:\Program Files\RemoteDisplayAnalyzer'.
4 |
5 | .DESCRIPTION
6 | This script downloads the Remote Display Analyzer and Connection Experience Indicator tools to the specified path.
7 | It creates the necessary directories and imports the required module before downloading the tools.
8 |
9 | .PARAMETER Path
10 | Specifies the path where the tools will be downloaded. The default path is 'C:\Program Files\RemoteDisplayAnalyzer'.
11 |
12 | .NOTES
13 | - This script requires the "Evergreen" module to be installed.
14 | - The script may require administrative privileges to create directories and download the tools.
15 | - The script may display warnings if the tools are already installed or if there are any issues during the download process.
16 | #>
17 |
18 | #description: Downloads the Remote Display Analyzer and Connection Experience Indicator
19 | #execution mode: Combined
20 | #tags: Evergreen, Remote Display Analyzer, Tools
21 | #Requires -Modules Evergreen
22 | [System.String] $Path = "$Env:ProgramFiles\RemoteDisplayAnalyzer"
23 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
24 |
25 | # Import shared functions written to disk by 000_PrepImage.ps1
26 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
27 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
28 | Write-LogFile -Message "Functions imported from: $FunctionFile"
29 |
30 | Write-LogFile -Message "Query Evergreen for Remote Display Analyzer and Connection Experience Indicator"
31 | $App = Get-EvergreenApp -Name "RDAnalyzer" | Select-Object -First 1
32 | Write-LogFile -Message "Downloading Remote Display Analyzer version $($App.Version) to $Path"
33 | Save-EvergreenApp -InputObject $App -CustomPath $Path -Force -ErrorAction "Stop" | Out-Null
34 |
35 | Write-LogFile -Message "Query Evergreen for Connection Experience Indicator"
36 | $App = Get-EvergreenApp -Name "ConnectionExperienceIndicator" | Select-Object -First 1
37 | Write-LogFile -Message "Downloading Connection Experience Indicator version $($App.Version) to $Path"
38 | Save-EvergreenApp -InputObject $App -CustomPath $Path -Force -ErrorAction "Stop" | Out-Null
39 |
--------------------------------------------------------------------------------
/actions/core/215_MicrosoftPowerShell.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs the latest Microsoft PowerShell.
4 |
5 | .DESCRIPTION
6 | This script installs the latest version of Microsoft PowerShell. It uses the Evergreen module to retrieve the latest stable release of PowerShell and installs it silently. The installation log is saved in the Nerdio Logs directory.
7 |
8 | .PARAMETER Path
9 | The installation path for Microsoft PowerShell. The default path is "$Env:SystemDrive\Apps\Microsoft\PowerShell".
10 |
11 | .EXAMPLE
12 | .\215_MicrosoftPowerShell.ps1
13 |
14 | This example runs the script to install the latest Microsoft PowerShell.
15 |
16 | .NOTES
17 | - Requires the Evergreen module.
18 | - Only installs the x64 architecture of Microsoft PowerShell.
19 | - The installation log is saved in "$Env:SystemRoot\Logs\ImageBuild".
20 | #>
21 |
22 | #description: Installs the latest Microsoft PowerShell
23 | #execution mode: Combined
24 | #tags: Evergreen, Microsoft, PowerShell
25 | #Requires -Modules Evergreen
26 | [System.String] $Path = "$Env:SystemDrive\Apps\Microsoft\PowerShell"
27 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
28 |
29 | # Import shared functions written to disk by 000_PrepImage.ps1
30 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
31 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
32 | Write-LogFile -Message "Functions imported from: $FunctionFile"
33 |
34 | #region Script logic
35 |
36 | $App = Get-EvergreenApp -Name "MicrosoftPowerShell" | `
37 | Where-Object { $_.Architecture -eq "x64" -and $_.Release -eq "Stable" } | `
38 | Select-Object -First 1
39 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
40 | Write-LogFile -Message "Microsoft PowerShell $($App.Version) downloaded to: $($OutFile.FullName)"
41 |
42 | $LogFile = "$Env:SystemRoot\Logs\ImageBuild\MicrosoftPowerShell$($App.Version).log" -replace " ", ""
43 | Write-LogFile -Message "Starting Microsoft PowerShell installation from: $($OutFile.FullName)"
44 | $params = @{
45 | FilePath = "$Env:SystemRoot\System32\msiexec.exe"
46 | ArgumentList = "/package `"$($OutFile.FullName)`" /quiet /norestart ALLUSERS=1 /log $LogFile"
47 | }
48 | Start-ProcessWithLog @params
49 | #endregion
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.toptal.com/developers/gitignore/api/macos,powershell,windows
2 | # Edit at https://www.toptal.com/developers/gitignore?templates=macos,powershell,windows
3 |
4 | ### macOS ###
5 | # General
6 | .DS_Store
7 | .AppleDouble
8 | .LSOverride
9 |
10 | # Icon must end with two \r
11 | Icon
12 |
13 |
14 | # Thumbnails
15 | ._*
16 |
17 | # Files that might appear in the root of a volume
18 | .DocumentRevisions-V100
19 | .fseventsd
20 | .Spotlight-V100
21 | .TemporaryItems
22 | .Trashes
23 | .VolumeIcon.icns
24 | .com.apple.timemachine.donotpresent
25 |
26 | # Directories potentially created on remote AFP share
27 | .AppleDB
28 | .AppleDesktop
29 | Network Trash Folder
30 | Temporary Items
31 | .apdisk
32 |
33 | ### macOS Patch ###
34 | # iCloud generated files
35 | *.icloud
36 |
37 | ### PowerShell ###
38 | # Exclude packaged modules
39 | *.zip
40 |
41 | # Exclude .NET assemblies from source
42 | *.dll
43 |
44 | ### Windows ###
45 | # Windows thumbnail cache files
46 | Thumbs.db
47 | Thumbs.db:encryptable
48 | ehthumbs.db
49 | ehthumbs_vista.db
50 |
51 | # Dump file
52 | *.stackdump
53 |
54 | # Folder config file
55 | [Dd]esktop.ini
56 |
57 | # Recycle Bin used on file shares
58 | $RECYCLE.BIN/
59 |
60 | # Windows Installer files
61 | *.cab
62 | *.msi
63 | *.msix
64 | *.msm
65 | *.msp
66 |
67 | # Windows shortcuts
68 | *.lnk
69 |
70 | # Others
71 | NerdioManagerVariables.json
72 | creds.json
73 | environment.json
74 |
75 | ## Terraform
76 | .terraform.lock.hcl
77 | *.tfplan
78 |
79 | # Local .terraform directories
80 | **/.terraform/*
81 |
82 | # .tfstate files
83 | *.tfstate
84 | *.tfstate.*
85 |
86 | # Crash log files
87 | crash.log
88 | crash.*.log
89 |
90 | # Exclude all .tfvars files, which are likely to contain sensitive data
91 | *.tfvars
92 | *.tfvars.json
93 |
94 | # Ignore override files as they are usually used to override resources locally
95 | override.tf
96 | override.tf.json
97 | *_override.tf
98 | *_override.tf.json
99 |
100 | # Ignore CLI configuration files
101 | .terraformrc
102 | terraform.rc
103 |
104 | # Ignore lock files (optional - remove if you want to commit these)
105 | # .terraform.lock.hcl
106 |
107 | # NME artifacts
108 | nme/artifacts/**
109 | nme/terraform-sf/**
110 |
--------------------------------------------------------------------------------
/actions/tools/Install-MicrosoftAzurePipelinesAgent.ps1:
--------------------------------------------------------------------------------
1 | #description: Installs the Microsoft Azure Pipelines agent to enable automated testing via Azure Pipelines. Do not run on production session hosts.
2 | #execution mode: Combined
3 | #tags: Evergreen, Testing, DevOps
4 | #Requires -Modules Evergreen
5 | [System.String] $Path = "$Env:SystemDrive\agents"
6 |
7 | # Check that the required variables have been set in Nerdio Manager
8 | foreach ($Value in "DevOpsUrl", "DevOpsPat", "DevOpsPool", "DevOpsUser", "DevOpsPassword") {
9 | if ($null -eq $SecureVars.$Value) { throw "$Value is $null" }
10 | }
11 |
12 | #region Script logic
13 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
14 |
15 | # Download
16 |
17 | $App = Get-EvergreenApp -Name "MicrosoftAzurePipelinesAgent" | `
18 | Where-Object { $_.Architecture -eq "x64" } | `
19 | Select-Object -First 1
20 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Env:Temp -WarningAction "SilentlyContinue"
21 |
22 | # Create the local account that the DevOps Pipelines agent service will run under
23 | $params = @{
24 | Name = $SecureVars.DevOpsUser
25 | Password = (ConvertTo-SecureString -String $SecureVars.DevOpsPassword -AsPlainText -Force)
26 | Description = "Azure Pipelines agent service for elevated exec."
27 | UserMayNotChangePassword = $true
28 | Confirm = $false
29 | }
30 | New-LocalUser @params
31 | Add-LocalGroupMember -Group "Administrators" -Member $SecureVars.DevOpsUser
32 |
33 | Expand-Archive -Path $OutFile.FullName -DestinationPath $Path -Force
34 | Push-Location -Path $Path
35 |
36 | # Agent install options
37 | $Options = "--unattended
38 | --url `"$($SecureVars.DevOpsUrl)`"
39 | --auth pat
40 | --token `"$($SecureVars.DevOpsPat)`"
41 | --pool `"$($SecureVars.DevOpsPool)`"
42 | --agent $Env:COMPUTERNAME
43 | --runAsService
44 | --windowsLogonAccount `"$($SecureVars.DevOpsUser)`"
45 | --windowsLogonPassword `"$($SecureVars.DevOpsPassword)`"
46 | --replace"
47 | $params = @{
48 | FilePath = "$Path\config.cmd"
49 | ArgumentList = $($Options -replace "\s+", " ")
50 | Wait = $true
51 | NoNewWindow = $true
52 | PassThru = $true
53 | }
54 | Start-Process @params
55 | #endregion
56 |
--------------------------------------------------------------------------------
/shell-apps/Microsoft/EdgeWebView2/Uninstall.ps1:
--------------------------------------------------------------------------------
1 | function Get-InstalledSoftware {
2 | $PropertyNames = "DisplayName", "DisplayVersion", "Publisher", "UninstallString", "PSPath", "WindowsInstaller",
3 | "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize", "SystemComponent"
4 | ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
5 | "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") | `
6 | ForEach-Object {
7 | Get-ItemProperty -Path $_ -Name $PropertyNames -ErrorAction "SilentlyContinue" | `
8 | . { process { if ($null -ne $_.DisplayName) { $_ } } } | `
9 | Select-Object -Property @{n = "Name"; e = { $_.DisplayName } }, @{n = "Version"; e = { $_.DisplayVersion } }, "Publisher",
10 | "UninstallString", @{n = "RegistryPath"; e = { $_.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } },
11 | "PSChildName", "WindowsInstaller", "InstallDate", "InstallSource", "HelpLink", "Language", "EstimatedSize" | `
12 | Sort-Object -Property "Name", "Publisher"
13 | }
14 | }
15 |
16 | function ConvertTo-UninstallCommand {
17 | [CmdletBinding()]
18 | param (
19 | [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
20 | [System.String]$UninstallString
21 | )
22 | begin {
23 | $regex = '(?i)"?([A-Z]:\\[^"]*?\.exe|[A-Za-z0-9._-]+\.exe)"?\s*((?:\S+\s*)*)'
24 | }
25 | process {
26 | if ($UninstallString -match $regex) {
27 | $Exe = $Matches[1]
28 | $Arguments = $Matches[2]
29 | [PSCustomObject]@{
30 | FilePath = if ($Exe -match "msiexec.exe") { "$Env:SystemRoot\System32\msiexec.exe" } else { $Exe }
31 | ArgumentList = ($Arguments -replace '\s+', ' ').Trim()
32 | }
33 | }
34 | else {
35 | return $null
36 | }
37 | }
38 | }
39 |
40 | $Uninstall = Get-InstalledSoftware | Where-Object { $_.Name -match "Microsoft Edge WebView2 Runtime" } | ConvertTo-UninstallCommand
41 | $params = @{
42 | FilePath = $Uninstall.FilePath
43 | ArgumentList = "$($Uninstall.ArgumentList) --force-uninstall"
44 | Wait = $true
45 | PassThru = $true
46 | NoNewWindow = $true
47 | ErrorAction = "Stop"
48 | }
49 | $result = Start-Process @params
50 | $Context.Log("Uninstall complete. Return code: $($result.ExitCode)")
51 |
--------------------------------------------------------------------------------
/actions/3rdparty/404_NotepadPlusPlus.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs the latest Notepad++ 64-bit with automatic updates disabled.
4 |
5 | .DESCRIPTION
6 | This script installs the latest version of Notepad++ 64-bit on the local machine. It also disables the automatic update feature of Notepad++.
7 |
8 | .PARAMETER Path
9 | Specifies the download path for Notepad++. The default path is "$Env:SystemDrive\Apps\NotepadPlusPlus".
10 |
11 | .NOTES
12 | - This script requires the "Evergreen" module.
13 | - The script will create a directory at the specified installation path if it does not already exist.
14 | - The script will create a directory at "$Env:SystemRoot\Logs\ImageBuild" if it does not already exist.
15 | - The script will download the latest version of Notepad++ from the Evergreen repository and install it silently.
16 | - The script will disable the automatic update feature of Notepad++ by renaming the updater folder.
17 | #>
18 |
19 | #description: Installs the latest Notepad++ 64-bit
20 | #execution mode: Combined
21 | #tags: Evergreen, Notepad++
22 | #Requires -Modules Evergreen
23 | [System.String] $Path = "$Env:SystemDrive\NotepadPlusPlus"
24 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
25 |
26 | # Import shared functions written to disk by 000_PrepImage.ps1
27 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
28 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
29 | Write-LogFile -Message "Functions imported from: $FunctionFile"
30 |
31 | Write-LogFile -Message "Query Evergreen for Notepad++ x64"
32 | $App = Get-EvergreenApp -Name "NotepadPlusPlus" | Where-Object { $_.Architecture -eq "x64" -and $_.Type -eq "exe" } | Select-Object -First 1
33 | Write-LogFile -Message "Downloading Notepad++ version $($App.Version) to $Path"
34 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
35 |
36 | $params = @{
37 | FilePath = $OutFile.FullName
38 | ArgumentList = "/S"
39 | }
40 | Start-ProcessWithLog @params
41 |
42 | # Disable updater
43 | $UpdaterPath = "$Env:ProgramFiles\Notepad++\updater"
44 | $RenamePath = "$Env:ProgramFiles\Notepad++\updater.disabled"
45 | if (Test-Path -Path $UpdaterPath) {
46 | if (Test-Path -Path $RenamePath) {
47 | Remove-Item -Path $RenamePath -Recurse -Force -ErrorAction "SilentlyContinue"
48 | }
49 | Rename-Item -Path $UpdaterPath -NewName "updater.disabled" -Force -ErrorAction "SilentlyContinue"
50 | }
51 |
--------------------------------------------------------------------------------
/actions/core/212_MicrosoftSQLServerManagementStudio.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs the latest Microsoft SQL Server Management Studio.
4 |
5 | .DESCRIPTION
6 | This script installs the latest version of Microsoft SQL Server Management Studio (SSMS) on the local machine.
7 | It utilizes the Evergreen module to download and install the specified version of SSMS.
8 |
9 | .PARAMETER Path
10 | Specifies the download path for SSMS. The default path is "$Env:SystemDrive\Apps\Microsoft\Ssms".
11 |
12 | .NOTES
13 | - This script requires the Evergreen module to be installed.
14 | - The script creates a log file in "$Env:SystemRoot\Logs\ImageBuild" to track the installation progress.
15 | - The script supports multiple languages, but it only installs the English version of SSMS.
16 | - The installation is performed silently without any user interaction.
17 | - The script checks if SSMS is already installed and skips the installation if it is.
18 | - The exit code of the installation process is logged for reference.
19 | #>
20 |
21 | #description: Installs the latest Microsoft SQL Server Management Studio
22 | #execution mode: Combined
23 | #tags: Evergreen, Microsoft, SQL Server
24 | #Requires -Modules Evergreen
25 | [System.String] $Path = "$Env:SystemDrive\Apps\Microsoft\Ssms"
26 | New-Item -Path $Path -ItemType "Directory" -Force -ErrorAction "SilentlyContinue" | Out-Null
27 |
28 | # Import shared functions written to disk by 000_PrepImage.ps1
29 | $FunctionFile = "$Env:TEMP\NerdioFunctions.psm1"
30 | Import-Module -Name $FunctionFile -Force -ErrorAction "Stop"
31 | Write-LogFile -Message "Functions imported from: $FunctionFile"
32 |
33 | #region Script logic
34 |
35 | $App = Get-EvergreenApp -Name "MicrosoftSsms" | `
36 | Where-Object { $_.Language -eq "English" } | Select-Object -First 1
37 | $OutFile = Save-EvergreenApp -InputObject $App -CustomPath $Path -ErrorAction "Stop"
38 | Write-LogFile -Message "Microsoft SQL Server Management Studio $($App.Version) downloaded to: $($OutFile.FullName)"
39 |
40 | $LogPath = (Get-LogFile).Path
41 | $LogFile = "$LogPath\MicrosoftSQLServerManagementStudio$($App.Version).log" -replace " ", ""
42 | Write-LogFile -Message "Starting Microsoft SQL Server Management Studio installation from: $($OutFile.FullName)"
43 | $params = @{
44 | FilePath = $OutFile.FullName
45 | ArgumentList = "/install /quiet /norestart DoNotInstallAzureDataStudio=1 /log $LogFile"
46 | }
47 | Start-ProcessWithLog @params
48 | #endregion
49 |
--------------------------------------------------------------------------------