Cheatsheet for PSAppDeployToolkit

I have been using PSAppDeployToolkit for the last 3-4 years – and I dont make any software package without using PSAppDeployToolkit.

If you dont know what I am talking about – please visit and download the wrapper here: https://psappdeploytoolkit.com/

After some years – I manage together with the list i found on github – to always include a powershell file with a variety of commands. So I always have it together with the package.

## Commonly used PSADT env variables $envCommonDesktop # C:\Users\Public\Desktop $envCommonPrograms # C:\ProgramData\Microsoft\Windows\Start Menu\Programs $envProgramFiles # C:\Program Files $envProgramFilesX86 # C:\Program Files (x86) $envProgramData # c:\ProgramData $envUserDesktop # c:\Users\\Desktop $envUserStartMenuPrograms # c:\Users\\AppData\Roaming\Microsoft\Windows\Start Menu\Programs $envSystemDrive # c: $envWinDir # c:\windows ## How to load ("dotsource") PSADT functions/variables for manual testing (your powershell window must be run as administrator first) cd "$path_to_PSADT_folder_youre_working_from" . .\AppDeployToolkit\AppDeployToolkitMain.ps1 ## *** Examples of exe install*** Execute-Process -Path '.exe' -Parameters '/quiet' -WaitForMsiExec:$true Execute-Process -Path "$dirFiles\DirectX\DXSetup.exe" -Parameters '/silent' -WindowStyle 'Hidden' #open notepad, don't wait for it to close before proceeding (i.e. continue with script) Execute-Process -Path "$envSystemRoot\notepad.exe" -NoWait #Execute an .exe, and hide confidential parameters from log file $serialisation_params = '-batchmode -quit -serial -username "" -password "SuperSecret123"' Execute-Process -Path "$envProgramFiles\Application\Serialise.exe" -Parameters "$serialisation_params" -SecureParameters:$True ##***Example to install an msi*** Execute-MSI -Action 'Install' -Path "$dirFiles\.msi" -Parameters 'REBOOT=ReallySuppress /QN' Execute-MSI -Action 'Install' -Path 'Discovery 2015.1.msi' #MSI install + transform file Execute-MSI -Action 'Install' -Path 'Adobe_Reader_11.0.0_EN.msi' -Transform 'Adobe_Reader_11.0.0_EN_01.mst' ## Install a patch Execute-MSI -Action 'Patch' -Path 'Adobe_Reader_11.0.3_EN.msp' ## To uninstall an MSI Execute-MSI -Action Uninstall -Path '' ## Uninstall a number of msi codes "", ` "", ` "", ` "", ` "", ` "" ` | % < Execute-MSI -Action 'Uninstall' -Path "$_" > ## ***Run a vbscript*** Execute-Process -Path "cscript.exe" -Parameters "$dirFiles\whatever.vbs" ## Copy something to all user profiles #grabbed from here: http://psappdeploytoolkit.com/forums/topic/copy-file-to-all-users-currently-logged-in-and-for-all-future-users/ $ProfilePaths = Get-UserProfiles | Select-Object -ExpandProperty 'ProfilePath' ForEach ($Profile in $ProfilePaths) < Copy-File -Path "$dirFiles\Example\example.ini" -Destination "$Profile\Example\To\Path\" >##***Remove registry key*** #I dont know the right term, but these are to delete the whole 'folder' reg key Remove-RegistryKey -Key 'HKEY_LOCAL_MACHINE\SOFTWARE\Macromedia\FlashPlayer\SafeVersions' -Recurse Remove-RegistryKey -Key 'HKLM:SOFTWARE\Macromedia\FlashPlayer\SafeVersions' -Recurse #This is to remove a specific reg key item from within a 'folder' Remove-RegistryKey -Key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' -Name 'RunAppInstall' Remove-RegistryKey -Key 'HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Run' -Name 'RunAppInstall' ## ***Create a reg key*** Set-RegistryKey -Key 'HKEY_LOCAL_MACHINE\SOFTWARE\LMKR\Licensing' -Name 'LMKR_LICENSE_FILE' -Value '@license'-Type String -ContinueOnError:$True ## ***To set an HKCU key for all users including default profile*** [scriptblock]$HKCURegistrySettings = < Set-RegistryKey -Key 'HKEY_CURRENT_USER\SOFTWARE\Classes\AppX4hxtad77fbk3jkkeerkrm0ze94wjf3s9' -Name 'NoOpenWith' -Value '""'-Type String -ContinueOnError:$True >Invoke-HKCURegistrySettingsForAllUsers -RegistrySettings $HKCURegistrySettings #import a .reg key, useful if there's a butt-tonne of nested keys/etc Execute-Process -FilePath "reg.exe" -Parameters "IMPORT `"$dirFiles\name-of-reg-export.reg`"" -PassThru #example 2 of importing a reg key, unsure if there's pros/cons to either approach. i've used above more than below. Execute-Process -Path "$envSystemRoot\regedit.exe" -Parameters "/s `"$dirFiles\geedee_all.reg`"" ## To pause script for time Start-Sleep -Seconds 120 ## ***To copy and overwrite a file*** Copy-File -Path "$dirSupportFiles\mms.cfg" -Destination "C:\Windows\SysWOW64\Macromed\Flash\mms.cfg" ## ***To copy a file*** Copy-File -Path "$dirSupportFiles\mms.cfg" -Destination "C:\Windows\SysWOW64\Macromed\Flash\" ## ***To copy a folder*** # pls note the destination should be the PARENT folder, not the folder name you want it to be. # for example, you'd copy "mozilla firefox" to "c:\program files", if you were wanting to copy the application files. # if copying to root of c:, include trailing slash - i.e. "$envSystemDrive\" not "$envSystemDrive" or "c:" Copy-File -Path "$dirFiles\client_1" -Destination "C:\oracle\product\11.2.0\" -Recurse ## ***To delete a file or shortcut*** Remove-File -Path "$envCommonDesktop\GeoGraphix Seismic Modeling.lnk" ## Remove a bunch of specific files "$envCommonDesktop\Example 1.lnk", ` "$envCommonDesktop\Example 2.lnk", ` "$envCommonDesktop\Example 3.lnk" ` | % < Remove-File -Path "$_" >## Remove a bunch of specific folders and their contents "$envSystemDrive\Example Dir1", ` "$envProgramFiles\Example Dir2", ` "$envProgramFiles\Example Dir3", ` "$envProgramFilesX86\Example Dir4", ` "$envSystemRoot\Example4" `` | % < Remove-Folder -Path "$_" >## Remove a bunch of specific folders, only if they're empty ( "$envProgramFiles\vendor\app\v12\junk", "$envProgramFiles\vendor\app\v12", "$envProgramFiles\vendor\app", "$envProgramFiles\vendor", "$envProgramFilesX86\vendor\app\v12\junk", "$envProgramFilesX86\vendor\app\v12", "$envProgramFilesX86\vendor\app", "$envProgramFilesX86\vendor" ) | % < if (!(Test-Path -Path "$_\*")) < Remove-Folder -Path "$_" >> # for each piped item, if the folder specified DOES NOT have contents ($folder\*), remove the folder ## Import a certificate to system 'Trusted Publishers' store.. helpful for clickOnce installers & importing drivers # (for references sake, I saved as base64, unsure if DER encoded certs work) Execute-Process -Path "certutil.exe" -Parameters "-f -addstore -enterprise TrustedPublisher `"$dirFiles\certname.cer`"" Write-Log -Message "Imported Cert" -Source $deployAppScriptFriendlyName ## Import a driver (note, >= win7 must be signed, and cert must be in trusted publishers store) Execute-Process -Path 'PnPutil.exe' -Parameters "/a `"$dirFiles\USB Drivers\driver.inf`"" ## Register a DLL module Execute-Process -FilePath "regsvr32.exe" -Parameters "/s `"$dirFiles\example\codec.dll`"" ## Make an install marker reg key for custom detections #for e.g. below would create something like: #HKLM:\SOFTWARE\PSAppDeployToolkit\InstallMarkers\Microsoft_KB2921916_1.0_x64_EN_01 Set-RegistryKey -Key "$configToolkitRegPath\$appDeployToolkitName\InstallMarkers\$installName" ## While loop pause (incase app installer exits immediately) #pause until example reg key While(!(test-path -path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\")) < sleep 5; Write-Log -Message "$appVendor - $appName - $appVersion is still not finished installing, sleeping another 5" -Source $deployAppScriptFriendlyName; >#pause until example file While(!(test-path -path "$envCommonDesktop\Example Shortcut.lnk")) < sleep 5; Write-Log -Message "$appVendor - $appName - $appVersion is still not finished installing, sleeping another 5" -Source $deployAppScriptFriendlyName; >##***To Create a shortcut*** New-Shortcut -Path "$envCommonPrograms\My Shortcut.lnk" ` -TargetPath "$envWinDir\system32\notepad.exe" ` -Arguments "--example-argument --example-argument-two" ` -Description 'Notepad' ` -WorkingDirectory "$envHomeDrive\$envHomePath" ## Modify ACL on a file #first load the ACL $acl_to_modify = "$envProgramData\Example\File.txt" $acl = Get-Acl "$acl_to_modify" #add another entry to the ACL list (in this case, add all users to have full control) $ar = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Users", "FullControl", "None", "None", "Allow") $acl.SetAccessRule($ar) #re-write the acl on the target file Set-Acl "$acl_to_modify" $acl ## Modify ACL on a folder $folder_to_change = "$envSystemDrive\Example_Folder" $acl = Get-Acl "$folder_to_change" $ar = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Users", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow") $acl.SetAccessRule($ar) Set-Acl "$folder_to_change" $acl ## Add to environment variables (specifically PATH in this case) # The first input in the .NET code can have Path subtituted for any other environemnt variable name (gci env: to see what is presently set) $path_addition = "C:\bin" #add $path_addition to permanent system wide path [Environment]::SetEnvironmentVariable("Path", $env:Path + ";" + $path_addition, "Machine") #add $path_addition to permanent user specific path [Environment]::SetEnvironmentVariable("Path", $env:Path + ";" + $path_addition, "User") #add $path_addition to the process level path only (i.e. when you quit script, it will no longer be applied) [Environment]::SetEnvironmentVariable("Path", $env:Path + ";" + $path_addition, "Process") #.NET 4.x comparison/install $version_we_require = [version]"4.5.2" $version_we_want_path = "$dirFiles\NDP452-KB2901907-x86-x64-AllOS-ENU.exe" $install_params = "/q /norestart" if((Get-RegistryKey "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -Value Version) -lt $version_we_require) < Write-Log -Source $deployAppScriptFriendlyName -Message ".NET version is < [string]$version_we_require, installing" Execute-Process -Path "$version_we_want_path" -Parameters "$install_params" -WaitForMSIExec:$true >#exit codes for reboot required #soft reboot " -Name "" -Value "" -Type String Set-RegistryKey -Key "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\" -Name "ComponentID" -Value "" -Type String Set-RegistryKey -Key "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\" -Name "Version" -Value "15,0,4420,1017" -Type String Set-RegistryKey -Key "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\" -Name "StubPath" -Value "$envWindir\Installer\LyncUserSettings.cmd" -Type String Set-RegistryKey -Key "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\" -Name "Locale" -Value "EN" -Type String #for reference, I've included the LyncUserSettings.cmd file as a springboard in this gist ## function to assist finding uninstall strings, msi codes, display names of installed applications # paste into powershell window (or save in (powershell profile)[http://www.howtogeek.com/50236/customizing-your-powershell-profile/] # usage once loaded: 'Get-Uninstaller chrome' function Get-Uninstaller < [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Name ) $local_key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*' $machine_key32 = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' $machine_key64 = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' $keys = @($local_key, $machine_key32, $machine_key64) Get-ItemProperty -Path $keys -ErrorAction 'SilentlyContinue' | ?< ($_.DisplayName -like "*$Name*") -or ($_.PsChildName -like "*$Name*") >| Select-Object PsPath,DisplayVersion,DisplayName,UninstallString,InstallSource,InstallLocation,QuietUninstallString,InstallDate > ## end of function