Configure BGInfo based on OU location
This is my way of automation to configure BGInfo on a server based on where in AD the server is located.
I have a customer where we need to deploy BGInfo with a background that informs the user logged on which Environment the server are connected to (Production, Acceptance, Test or Tier-0) and by using the computername and do a query to the AD to get the OU path for the server it runs the bginfo with the correct configfile for BGInfo.
By doing this i now have one package that i can deploy to one collection and leave it to the script to set the correct backgound after logon for the user.
But before you can use the script you need configure manually BGInfo with company logo, background pictures and choose colors and save a configfile for each environment. All files need to be saved in the same folder as the script.
At the end you will find Deploy-Application.ps1 used in AppDeploy Toolkit which i used in deploying it in MEMCM.
Download links
- My files at Github
- AppDeploy Toolkit
- BGInfo (Use the 64bit version)
Folderstructure
In my test-environment i have the following structure.
My BGInfo-folder are in the root of C: and it contains the followling files
- Bginfo64.exe – Exe-file downloaded from https://docs.microsoft.com/en-us/sysinternals/downloads/bginfo (Please use 64bit version)
- bginfoAcc.bgi – Configfile for BGInfo for servers in OU named Acceptance
- bginfoProd.bgi – Configfile for BGInfo for servers in OU named Production
- bginfoTest.bgi – Configfile for BGInfo for servers in OU named Test
- bginfoTier.bgi – Configfile for BGInfo for servers in OU named Tier
- bginfo.bmp – Picture generated by BGInfo
- Acceptance.jpg – Backgroundpicture for servers in OU named Acceptance
- Production.jpg – Backgroundpicture for servers in OU named Producution
- Test.jpg – Backupgroundpicture for servers in OU named Test
- Tier.jpg – Backgroundpicture for servers in OU named Tier
- BGinfo.log – Logfile for the script, can be placed where ever you want – Settings in script
- Run.bat – Bat-file that runs the script on logon. Script generated.
- Set-BGInfo.ps1 – The script
- BGInfo.xml – XML file that holds which OU should have which configurationfile
Check the AD
In the script a have the following part that get the computername and extract the OUpath and by filter the result you will get a searchable string to compare with the xml-file.
Note: This part of the script is not created by me…It´s created by a friend of mine who has expert knowledge in powershell 🙂
1 2 3 4 5 6 7 8 9 10 11 12 |
$strName = $env:COMPUTERNAME $strNamesearch = "$($strName)$" $strFilter = "(&(objectCategory=Computer)(samAccountName=$strNamesearch))" $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.Filter = $strFilter $objPath = $objSearcher.FindOne() $objDetails = $objPath.GetDirectoryEntry() $objDetails.RefreshCache("canonicalName") $OUPath = ($objDetails.canonicalname -replace "/$($strName)") -replace "$domainname/" |
The result in the logfile:
The XML-file
The XML-file holds info about which OU should have which Configfile.
When the scripts compares $OUpath with XML-file with the following script part
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# Compare OU-path with variable and run BGInfo # Check XML after which configfile to use [XML]$xmlfile = Get-Content .\BGinfo.xml write-log -Level INFO -Message 'Checking XML-file' foreach ($item in $xmlfile.bginfo.setup.name) { if($OUPath -like "*$item*") { $ExtractedValue = $item } } $data = $xmlfile.BGInfo.Setup | Where-Object {$_.name -contains $ExtractedValue} # configfile to use $bginfoconfig = $data.config |
The logfile register the following result after having the server in a OU called Production.
The bat-file & Registry run
I had some problem to run only the powershellscript on logon and had to use Run.bat instead. To automate this i had to generate the correct Run.bat based on where you install your BGInfo configuration
The following script part generate the Run.bat and save it in the same folder as the script it also add the path to Run.bat to the registry so it runs every time a user logon the server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
if($Firstrun -eq $true) { Write-Log -Level INFO -Message 'Delete run.bat if exist' Remove-Item $PSScriptRoot\run.bat -Force -ErrorAction SilentlyContinue write-log -Level INFO -Message 'New run.bat created' New-Item "$PSScriptRoot\run.bat" -ItemType File -Value "@echo off" Add-Content "$PSScriptRoot\run.bat" "" Add-Content "$PSScriptRoot\run.bat" "cd $PSScriptRoot" Add-Content "$PSScriptRoot\run.bat" "PowerShell.exe -ExecutionPolicy Bypass -File $PSScriptRoot\set-bginfo.ps1" write-log -Level INFO -Message 'Added content to run.bat' #Registry run check for BGinfo run $RegistryRunVaule = Get-ItemProperty -Path $registrypath -Name BGinfo -ErrorAction SilentlyContinue if ($RegistryRunVaule -eq $null) { write-host "RegistryRun missing value, adding it to Registry" -ForegroundColor Green write-log -Level INFO -Message 'Missing registrysetting for run' New-ItemProperty -Path $registrypath -Name BGInfo -PropertyType string -Value "$PSScriptRoot\run.bat" write-log -Level INFO -Message 'Registry value added' } else { Write-host "Registry for run exist but will be updated" -ForegroundColor green write-log -Level INFO -Message 'Registryvalue exist but will be updated' New-ItemProperty -Path $registrypath -Name BGInfo -PropertyType string -Value "$PSScriptRoot\run.bat" -Force } } |
The batfile the runs everytime a user logon the server looks like this:
1 2 3 |
@echo off cd C:\BgInfo PowerShell.exe -ExecutionPolicy Bypass -File C:\BgInfo\set-bginfo.ps1 |
The script Set-BGInfo.ps1 Complete
I attach the script here for you to study…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
<# .Synopsis Configure BGinfo based on OU .DESCRIPTION When running the script it check´s where the server is located in the AD and extract the path to configure BGinfo for the right environment .EXAMPLE Set-BGInfo.ps1 Basic run .EXAMPLE Set-BGInfo.ps1 -FirstRun When running the script for the first time it will create/update registry value for run and will generate a new run.bat with the values to autorun bginfo when a user log on the server/client. .EXAMPLE Set-BGInfo.ps1 -Reset Removes registry run value if BGinfo is removed or BGinfo folder is moved. .NOTES Filename: Set-BGInfo.ps1 Author: Christian Damberg Website: https://www.damberg.org Email: christian@damberg.org Modified date: 2022-04-04 Version 1.0 - First release For the script to work you need to have configured BGinfo for your environment. Downloadlink and instructions for BGInfo https://docs.microsoft.com/en-us/sysinternals/downloads/bginfo You need to change the value for domainname in the script. The logfile for the script is by default located in the same folder as the script. If you want the logfile at another place you can change it in the script. You must create all of your configfiles for bginfo with logos and colors and save them in the same folder as the script. Update the xml-file with what configfile you want to use with which OU-name. To use this script you must have OU-name connected to something that explain environment or something unique to keep servers apart. Exempel on OU-structure - Servers - 2012 r2 - Production - Acceptance - Test - 2016 - Production - Acceptance - test - 2019 - Production - Acceptance - Test #> #------------------------------------------------# # Parameters Param( [Parameter(Mandatory=$false)] [Switch]$Firstrun, [Parameter(Mandatory=$false)] [Switch]$Reset ) #------------------------------------------------# # Functions in script # Function to write to logfile Function Write-Log { [CmdletBinding()] Param( [Parameter(Mandatory=$False)] [ValidateSet("INFO","WARN","ERROR","FATAL","DEBUG")] [String] $Level = "INFO", [Parameter(Mandatory=$True)] [string] $Message ) $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss") $Line = "$Stamp $Level $Message" "$Stamp $Level $Message" | Out-File -Encoding utf8 $logfile -Append } #------------------------------------------------# # Variables to the script [string]$DomainName = "corp.viamonstra.com" [string]$registrypath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" [String]$logfile = "$PSScriptRoot\BGinfo.log" #------------------------------------------------# # Firstrun check if($Firstrun -eq $true) { Write-Log -Level INFO -Message 'Delete run.bat if exist' Remove-Item $PSScriptRoot\run.bat -Force -ErrorAction SilentlyContinue write-log -Level INFO -Message 'New run.bat created' New-Item "$PSScriptRoot\run.bat" -ItemType File -Value "@echo off" Add-Content "$PSScriptRoot\run.bat" "" Add-Content "$PSScriptRoot\run.bat" "cd $PSScriptRoot" Add-Content "$PSScriptRoot\run.bat" "PowerShell.exe -ExecutionPolicy Bypass -File $PSScriptRoot\set-bginfo.ps1" write-log -Level INFO -Message 'Added content to run.bat' #Registry run check for BGinfo run $RegistryRunVaule = Get-ItemProperty -Path $registrypath -Name BGinfo -ErrorAction SilentlyContinue if ($RegistryRunVaule -eq $null) { write-host "RegistryRun missing value, adding it to Registry" -ForegroundColor Green write-log -Level INFO -Message 'Missing registrysetting for run' New-ItemProperty -Path $registrypath -Name BGInfo -PropertyType string -Value "$PSScriptRoot\run.bat" write-log -Level INFO -Message 'Registry value added' } else { Write-host "Registry for run exist but will be updated" -ForegroundColor green write-log -Level INFO -Message 'Registryvalue exist but will be updated' New-ItemProperty -Path $registrypath -Name BGInfo -PropertyType string -Value "$PSScriptRoot\run.bat" -Force } } if($reset -eq $true) { Remove-ItemProperty -Path $registrypath -Name BGINFO -ErrorAction SilentlyContinue write-host 'Settings in Registry deleted' -ForegroundColor Red write-log -Level INFO -Message 'Registryvalue removed for running bginfo config at logon' write-log -Level INFO -Message 'Exist script' exit } #------------------------------------------------# # query to verify OU-path $strName = $env:COMPUTERNAME $strNamesearch = "$($strName)$" $strFilter = "(&(objectCategory=Computer)(samAccountName=$strNamesearch))" $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.Filter = $strFilter $objPath = $objSearcher.FindOne() $objDetails = $objPath.GetDirectoryEntry() $objDetails.RefreshCache("canonicalName") $OUPath = ($objDetails.canonicalname -replace "/$($strName)") -replace "$domainname/" Write-Log -Level INFO "Find the following value when checking OU path for $env:COMPUTERNAME : $OUPath" #------------------------------------------------# # Compare OU-path with variable and run BGInfo # Check XML after which configfile to use [XML]$xmlfile = Get-Content .\BGinfo.xml write-log -Level INFO -Message 'Checking XML-file' foreach ($item in $xmlfile.bginfo.setup.name) { if($OUPath -like "*$item*") { $ExtractedValue = $item } } $data = $xmlfile.BGInfo.Setup | Where-Object {$_.name -contains $ExtractedValue} # configfile to use $bginfoconfig = $data.config Write-log -Level INFO -Message "The script will use $bginfoconfig when running" # Construct executecommand $bgInfoExecutePath = "$PSScriptRoot\Bginfo64.exe /i$PSScriptRoot\$bgInfoConfig /timer:0 /silent /NOLICPROMPT" # Run BGinfo with BGinfo config write-log -Level INFO -Message "Running BGinfo with $bgInfoExecutePath" Invoke-Expression $bgInfoExecutePath |
Howto deploy it…MEMCM or Manually
It´s up to you how you want to deploy it.
If you want to deploy it manually to a server you need to copy the files to a folder on the server and run the “-Firstrun” parameter in the script.
If you want to deploy it with MEMCM and you are familiar with AppDeploy Toolkit (Website) you will find my Deploy-Application.ps1 at my Github in the same folder as the script or copy it from here:
There are two things you have to add or create in your deployment if you don´t use the scripts parameter “Firstrun”
- Create a Run.bat file manually
- Add run.bat in the registry to run at logon by user
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
<# .SYNOPSIS This script performs the installation or uninstallation of an application(s). # LICENSE # PowerShell App Deployment Toolkit - Provides a set of functions to perform common application deployment tasks on Windows. Copyright (C) 2017 - Sean Lillis, Dan Cunningham, Muhammad Mashwani, Aman Motazedian. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. .DESCRIPTION The script is provided as a template to perform an install or uninstall of an application(s). The script either performs an "Install" deployment type or an "Uninstall" deployment type. The install deployment type is broken down into 3 main sections/phases: Pre-Install, Install, and Post-Install. The script dot-sources the AppDeployToolkitMain.ps1 script which contains the logic and functions required to install or uninstall an application. .PARAMETER DeploymentType The type of deployment to perform. Default is: Install. .PARAMETER DeployMode Specifies whether the installation should be run in Interactive, Silent, or NonInteractive mode. Default is: Interactive. Options: Interactive = Shows dialogs, Silent = No dialogs, NonInteractive = Very silent, i.e. no blocking apps. NonInteractive mode is automatically set if it is detected that the process is not user interactive. .PARAMETER AllowRebootPassThru Allows the 3010 return code (requires restart) to be passed back to the parent process (e.g. SCCM) if detected from an installation. If 3010 is passed back to SCCM, a reboot prompt will be triggered. .PARAMETER TerminalServerMode Changes to "user install mode" and back to "user execute mode" for installing/uninstalling applications for Remote Destkop Session Hosts/Citrix servers. .PARAMETER DisableLogging Disables logging to file for the script. Default is: $false. .EXAMPLE powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeployMode 'Silent'; Exit $LastExitCode }" .EXAMPLE powershell.exe -Command "& { & '.\Deploy-Application.ps1' -AllowRebootPassThru; Exit $LastExitCode }" .EXAMPLE powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeploymentType 'Uninstall'; Exit $LastExitCode }" .EXAMPLE Deploy-Application.exe -DeploymentType "Install" -DeployMode "Silent" .NOTES Toolkit Exit Code Ranges: 60000 - 68999: Reserved for built-in exit codes in Deploy-Application.ps1, Deploy-Application.exe, and AppDeployToolkitMain.ps1 69000 - 69999: Recommended for user customized exit codes in Deploy-Application.ps1 70000 - 79999: Recommended for user customized exit codes in AppDeployToolkitExtensions.ps1 .LINK http://psappdeploytoolkit.com #> [CmdletBinding()] Param ( [Parameter(Mandatory=$false)] [ValidateSet('Install','Uninstall')] [string]$DeploymentType = 'Install', [Parameter(Mandatory=$false)] [ValidateSet('Interactive','Silent','NonInteractive')] [string]$DeployMode = 'Interactive', [Parameter(Mandatory=$false)] [switch]$AllowRebootPassThru = $false, [Parameter(Mandatory=$false)] [switch]$TerminalServerMode = $false, [Parameter(Mandatory=$false)] [switch]$DisableLogging = $false ) Try { ## Set the script execution policy for this process Try { Set-ExecutionPolicy -ExecutionPolicy 'ByPass' -Scope 'Process' -Force -ErrorAction 'Stop' } Catch {} ##*=============================================== ##* VARIABLE DECLARATION ##*=============================================== ## Variables: Application [string]$appVendor = 'Microsoft' [string]$appName = 'BGInfo' [string]$appVersion = '1.0' [string]$appArch = '' [string]$appLang = 'EN' [string]$appRevision = '01' [string]$appScriptVersion = '1.0.0' [string]$appScriptDate = '5/4/2022' [string]$appScriptAuthor = 'Christian Damberg, Cygate' [string]$appUninstallGUID = '{}' [string]$appRegDisplayName = 'paint.net' [string]$ApplicationsToClose = 'dummy' # process name WITHOUT .exe extension [string]$AppRegName = $appName [String]$InstallationPath = 'c:\BGinfo' [string]$registrypath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" ##*=============================================== ## Variables: Install Titles (Only set here to override defaults set by the toolkit) [string]$installName = '' [string]$installTitle = '' ##* Do not modify section below #region DoNotModify ## Variables: Exit Code [int32]$mainExitCode = 0 ## Variables: Script [string]$deployAppScriptFriendlyName = 'Deploy Application' [version]$deployAppScriptVersion = [version]'3.8.0' [string]$deployAppScriptDate = '23/09/2019' [hashtable]$deployAppScriptParameters = $psBoundParameters ## Variables: Environment If (Test-Path -LiteralPath 'variable:HostInvocation') { $InvocationInfo = $HostInvocation } Else { $InvocationInfo = $MyInvocation } [string]$scriptDirectory = Split-Path -Path $InvocationInfo.MyCommand.Definition -Parent ## Dot source the required App Deploy Toolkit Functions Try { [string]$moduleAppDeployToolkitMain = "$scriptDirectory\AppDeployToolkit\AppDeployToolkitMain.ps1" If (-not (Test-Path -LiteralPath $moduleAppDeployToolkitMain -PathType 'Leaf')) { Throw "Module does not exist at the specified location [$moduleAppDeployToolkitMain]." } If ($DisableLogging) { . $moduleAppDeployToolkitMain -DisableLogging } Else { . $moduleAppDeployToolkitMain } } Catch { If ($mainExitCode -eq 0){ [int32]$mainExitCode = 60008 } Write-Error -Message "Module [$moduleAppDeployToolkitMain] failed to load: `n$($_.Exception.Message)`n `n$($_.InvocationInfo.PositionMessage)" -ErrorAction 'Continue' ## Exit the script, returning the exit code to SCCM If (Test-Path -LiteralPath 'variable:HostInvocation') { $script:ExitCode = $mainExitCode; Exit } Else { Exit $mainExitCode } } #endregion ##* Do not modify section above ##*=============================================== ##* END VARIABLE DECLARATION ##*=============================================== If ($deploymentType -ine 'Uninstall') { ##*=============================================== ##* PRE-INSTALLATION ##*=============================================== [string]$installPhase = 'Pre-Installation' ## Show Welcome Message, close Internet Explorer if required, allow up to 3 deferrals, verify there is enough disk space to complete the install, and persist the prompt Show-InstallationWelcome -CloseApps "$ApplicationsToClose" -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt ## Show Progress Message (with the default message) Show-InstallationProgress ## <Perform Pre-Installation tasks here> ##*=============================================== ##* INSTALLATION ##*=============================================== [string]$installPhase = 'Installation' ## <Perform Installation tasks here> Write-Log -Message "Creating BGInfo folder at $InstallationPath" -Severity 1 -LogType CMTrace New-Folder -Path $InstallationPath -ContinueOnError $true Write-log -Message "Copying files from Dirfiles to $InstallationPath" Copy-File -Path "$dirfiles\*" -Destination $InstallationPath -Recurse -ContinueOnError $true Write-Log -Message "Creating Run.Bat in folder $InstallationPath" -Severity 1 -LogType CMTrace New-Item "$InstallationPath\run.bat" -ItemType File -Value "@echo off" Add-Content "$InstallationPath\run.bat" "" Add-Content "$InstallationPath\run.bat" "cd $InstallationPath" Add-Content "$InstallationPath\run.bat" "PowerShell.exe -ExecutionPolicy Bypass -File $InstallationPath\set-bginfo.ps1" Write-Log -Message "Adding $InstallationPath\run.bat to $registrypath" -Severity 1 -LogType CMTrace New-ItemProperty -Path $registrypath -Name BGInfo -PropertyType string -Value "$InstallationPath\run.bat" -Force # $Process = Start-Process -FilePath "$dirfiles\Dummy.exe" -ArgumentList "/silent" -NoNewWindow -Wait -PassThru -ErrorAction SilentlyContinue # $ErrorCode = $Process.ExitCode # Write-Log "$appRegDisplayName installed with exit code: $ErrorCode" ##*=============================================== ##* POST-INSTALLATION ##*=============================================== [string]$installPhase = 'Post-Installation' ## <Perform Post-Installation tasks here> # Remove desktop icon if (Test-Path "$env:PUBLIC\Desktop\Dummy.lnk") { Remove-File -Path "$env:PUBLIC\Desktop\Dummy.lnk" } } ElseIf ($deploymentType -ieq 'Uninstall') { ##*=============================================== ##* PRE-UNINSTALLATION ##*=============================================== [string]$installPhase = 'Pre-Uninstallation' ## Show Welcome Message, close Internet Explorer with a 60 second countdown before automatically closing Show-InstallationWelcome -CloseApps "$ApplicationsToClose" -CloseAppsCountdown 60 ## Show Progress Message (with the default message) Show-InstallationProgress ## <Perform Pre-Uninstallation tasks here> ##*=============================================== ##* UNINSTALLATION ##*=============================================== [string]$installPhase = 'Uninstallation' # <Perform Uninstallation tasks here> #Remove-MSIApplications -Name "$appRegDisplayName" ##*=============================================== ##* POST-UNINSTALLATION ##*=============================================== [string]$installPhase = 'Post-Uninstallation' ## <Perform Post-Uninstallation tasks here> Remove-RegistryKey -Key "HKLM:\SOFTWARE\Cygate\Applications\$AppRegName" -ContinueOnError:$True } ##*=============================================== ##* END SCRIPT BODY ##*=============================================== ## Call the Exit-Script function to perform final cleanup operations Set-RegistryKey -Key "HKLM:\SOFTWARE\Cygate\Applications\$AppRegName" -Name "InstallStatus" -Value '1' -Type String -ContinueOnError:$True Set-RegistryKey -Key "HKLM:\SOFTWARE\Cygate\Applications\$AppRegName" -Name "AppVersion" -Value $appVersion -Type String -ContinueOnError:$True Exit-Script -ExitCode $mainExitCode } Catch { Set-RegistryKey -Key "HKLM:\SOFTWARE\Cygate\Applications\$AppRegName" -Name "InstallStatus" -Value '0' -Type String -ContinueOnError:$True [int32]$mainExitCode = 60001 [string]$mainErrorMessage = "$(Resolve-Error)" Write-Log -Message $mainErrorMessage -Severity 3 -Source $deployAppScriptFriendlyName Show-DialogBox -Text $mainErrorMessage -Icon 'Stop' Exit-Script -ExitCode $mainExitCode } |
You must be logged in to post a comment.