Skip to content

Instantly share code, notes, and snippets.

@elgrunt0
Forked from leeramsay/PSADT-Cheatsheet.ps1
Last active June 12, 2020 07:23
Show Gist options
  • Save elgrunt0/a61afec3db0792dbd6443ccc9b7cec98 to your computer and use it in GitHub Desktop.
Save elgrunt0/a61afec3db0792dbd6443ccc9b7cec98 to your computer and use it in GitHub Desktop.
PSADT snippits/cheatsheet

This is a small gist with snippits I frequently use in PSADT - PowerShell App Deployment Toolkit.

I've also stole a few from here to get started, I've populated a bunch I use regularly.

Be careful with the scripters inc link above^^ however, all of the quotes are funky UTF-8 and don't paste into a terminal without errors (all the quotes in this gist have been checked).

Also, additional note that isn't strictly related to PSADT, but is helpful in deployment matters.. I've included an example_app.exe.manifest file. From what I can see, when you come across a legacy app that requests administrator privilige on launch (but does not have 'run as administrator' checked in it's properties, you can overrule this behaviour by creating .exe.manifest file (named in accordance with the .exe's file name), with the following within the file:

<requestedExecutionLevel level="asInvoker" uiAccess="false"/>

As opposed to:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>

See example in this repo, or read more here and here

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0"
processorArchitecture="X86"
name="Example_App.exe"
type="win32"/>
<description>elevate execution level</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
## 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\{user currently logged in}\Desktop
$envUserStartMenuPrograms # c:\Users\{user currently logged in}\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 '<application>.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 <aa-bb-cc-dd-ee-ffff11111> -username "<serialisation 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\<application>.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 '{5708517C-59A3-45C6-9727-6C06C8595AFD}'
## Uninstall a number of msi codes
"{2E873893-A883-4C06-8308-7B491D58F3D6}", <# Example #>`
"{2E873893-A883-4C06-8308-7B491D58F3D6}", <# Example #>`
"{2E873893-A883-4C06-8308-7B491D58F3D6}", <# Example #>`
"{2E873893-A883-4C06-8308-7B491D58F3D6}", <# Example #>`
"{2E873893-A883-4C06-8308-7B491D58F3D6}", <# Example #>`
"{B234DC00-1003-47E7-8111-230AA9E6BF10}" <# Last example cannot have a comma after the double quotes #>`
| % { Execute-MSI -Action 'Uninstall' -Path "$_" } <# foreach item, uninstall #>
## ***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 = {
# I included both to illustrate that HKCU\ is an acceptable abbreviation
Set-RegistryKey -Key 'HKEY_CURRENT_USER\SOFTWARE\Classes\AppX4hxtad77fbk3jkkeerkrm0ze94wjf3s9' -Name 'NoOpenWith' -Value '""'-Type String -ContinueOnError:$True -SID $UserProfile.SID
Set-RegistryKey -Key 'HKCU\Software\Microsoft\Office\14.0\Common' -Name 'qmenable' -Value 0 -Type DWord -SID $UserProfile.SID
}
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 <x> 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", <# Example #>`
"$envCommonDesktop\Example 2.lnk", <# Example #>`
"$envCommonDesktop\Example 3.lnk" <# Careful with the last item to not include a comma after the double quote #>`
| % { Remove-File -Path "$_" }
## Remove a bunch of specific folders and their contents
"$envSystemDrive\Example Dir1", <# Example #>`
"$envProgramFiles\Example Dir2", <# Example #>`
"$envProgramFiles\Example Dir3", <# Example #>`
"$envProgramFilesX86\Example Dir4", <# Example #>`
"$envSystemRoot\Example4" <# Careful with the last item to not include a comma after the double quote #>``
| % { Remove-Folder -Path "$_" }
## Remove a bunch of specific folders, only if they're empty
<# Use this by specifying folders from "deepest folder level" to "most shallow folder level" order e.g.
c:\program files\vendor\app\v12\junk - then
c:\program files\vendor\app\v12 - then
c:\program files\vendor\app - then
c:\program files\vendor
using the above example, it will only remove c:\program files\vendor if every other folder above is completely empty.
if for example v11 was also installed, it would stop prior #>
(
"$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" <# careful not to include the comma after the double quotes in this one #>
) | % { 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\{product-code-hereD}")) {
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 <- will not 'force' restart, and sccm will progress past, but will nag to restart afterward
Exit-Script -ExitCode 3010
#hard reboot <- does not 'force' restart, but sccm won't proceed past any pre-reqs without reboot
Exit-Script -ExitCode 1641
##Create Active Setup to Update User Settings
#1
Copy-File -Path "$dirFiles\Example.exe" -Destination "$envProgramData\Example"
Set-ActiveSetup -StubExePath "$envProgramData\Example\Example.exe" `
-Description 'AutoDesk BIM Glue install' `
-Key 'Autodesk_BIM_Glue_Install' `
-ContinueOnError:$true
#2
Copy-File -Path "$dirSupportFiles\LyncUserSettings.cmd" -Destination "$envWindir\Installer\LyncUserSettings.cmd"
Set-RegistryKey -Key "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\{90150000-012B-0409-0000-0000000FF1CE}" -Name "" -Value "{90150000-012B-0409-0000-0000000FF1CE}" -Type String
Set-RegistryKey -Key "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\{90150000-012B-0409-0000-0000000FF1CE}" -Name "ComponentID" -Value "{90150000-012B-0409-0000-0000000FF1CE}" -Type String
Set-RegistryKey -Key "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\{90150000-012B-0409-0000-0000000FF1CE}" -Name "Version" -Value "15,0,4420,1017" -Type String
Set-RegistryKey -Key "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\{90150000-012B-0409-0000-0000000FF1CE}" -Name "StubPath" -Value "$envWindir\Installer\LyncUserSettings.cmd" -Type String
Set-RegistryKey -Key "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\{90150000-012B-0409-0000-0000000FF1CE}" -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
$expected_checksum = "A7BBC4B4F781E04214ECEBE69A766C76681AA7EB"
$file_to_checksum = "c:\windows\notepad.exe"
#$Algorithm = "sha1" #must be sha1 or md5, default sha1
function Get-Checksum
{
Param (
[string]$File=$(throw("You must specify a filename to get the checksum of.")),
[ValidateSet("sha1","md5")]
[string]$Algorithm="sha1"
)
if ($File -match '^\.\\') { $File = (get-item $File).FullName }
$fs = new-object System.IO.FileStream $File, "Open", "Read", "Read"
$algo = [type]"System.Security.Cryptography.$Algorithm"
$crypto = $algo::Create()
$hash = [BitConverter]::ToString($crypto.ComputeHash($fs)).Replace("-", "")
$fs.Close()
$hash
}
if (test-path -PathType Leaf $file_to_checksum) { $current_checksum = get-checksum -file $file_to_checksum }
if ($expected_checksum -eq $current_checksum) { Write-Host "Installed" }
$expected_version = [version]"4.6.2"
If( (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full").Version -ge $expected_version) { Write-Host "Installed" }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment