Last active
May 22, 2023 13:40
-
-
Save rileyz/1786685955734ffee97a1c2e89567049 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Script to assist with deploying App-V packages to users, for user publishing based testing. | |
.DESCRIPTION | |
Intended Use | |
This script was produced to assist in publishing packages to users, removing the arduous task | |
of discovering the target users SID. | |
This is for user published based testing, not globally published applications testing. | |
Valid for App-V 5.0 SP2 Hotfix 5 and greater. | |
Example | |
Logon as the test user, launch an elevate PowerShell console and execute this script. The script | |
will discover all logged on users, even switched users. The Execution Policy must allow scripts | |
to run. | |
Run the script from a PowerShell or PowerShell ISE console. The App-V packages should be in the | |
current working directory of the console. | |
* PowerShell console. | |
AddAndPublish-AppvClientPackageToSID.ps1 | |
* PowerShell ISE. | |
Run script, or press F5. | |
About | |
I got disgruntled of having to discover a target SID when in depth testing was required for | |
complex applications. After numerous occasions this PowerShell script was created, while | |
resolving the need, it was also was a chance to improve my PowerShell skills. | |
Known Defects/Bugs | |
* The target needs to have an active session! No error trapping has been provided for this event. | |
Code Snippet Credits | |
* https://learn-powershell.net/2010/11/01/quick-hit-find-currently-logged-on-users | |
* https://blogs.msdn.microsoft.com/mpeder/2014/10/07/convert-sid-to-user-name-using-powershell | |
Version History | |
1.03 22/05/2023 | |
Updated self-identity discovery to use .Net method. | |
Fixed missing leading zero's padding when user selection is greater than nine. | |
1.02 07/04/2022 | |
Added support for packages with Deployment Configuration and User Configuration XML. | |
1.01 23/12/2016 | |
Fixed Active Session detection by using different function. | |
Added detection for your elevated session. | |
Added support for packages with and without User Configuration XML. | |
Added support for multiple packages. | |
1.00 20/10/2016 | |
Initial release. | |
Copyright & Intellectual Property | |
Feel to copy, modify and redistribute, but please pay credit where it is due. | |
Feedback is welcome, please contact me on LinkedIn. | |
.LINK | |
Author:.......http://www.linkedin.com/in/rileylim | |
Source Code:..https://gist.github.com/rileyz/1786685955734ffee97a1c2e89567049 | |
Article:......http://www.itninja.com/blog/view/app-v-publish-to-user-sid-script | |
.EXAMPLE | |
PowerShell console. | |
AddAndPublish-AppvClientPackageToSID.ps1 | |
PowerShell ISE. | |
Run script, or press F5. | |
#> | |
# Function List ################################################################################### | |
Function Get-ComputerSessions { | |
<# | |
.SYNOPSIS | |
Retrieves tall user sessions from local or remote server/s | |
.DESCRIPTION | |
Retrieves tall user sessions from local or remote server/s | |
.PARAMETER computer | |
Name of computer/s to run session query against. | |
.NOTES | |
Name: Get-ComputerSessions | |
Author: Boe Prox | |
DateCreated: 01Nov2010 | |
.LINK | |
https://boeprox.wordpress.org | |
.EXAMPLE | |
Get-ComputerSessions -computer "server1" | |
Description | |
----------- | |
This command will query all current user sessions on 'server1'. | |
#> | |
[cmdletbinding( | |
DefaultParameterSetName = 'session', | |
ConfirmImpact = 'low' | |
)] | |
Param( | |
[Parameter( | |
Mandatory = $True, | |
Position = 0, | |
ValueFromPipeline = $True)] | |
[string[]]$computer | |
) | |
Begin { | |
$report = @() | |
} | |
Process { | |
ForEach($c in $computer) { | |
# Parse 'query session' and store in $sessions: | |
$sessions = query session /server:$c | |
1..($sessions.count -1) | % { | |
$temp = "" | Select Computer,SessionName, Username, Id, State, Type, Device | |
$temp.Computer = $c | |
$temp.SessionName = $sessions[$_].Substring(1,18).Trim() | |
$temp.Username = $sessions[$_].Substring(19,20).Trim() | |
$temp.Id = $sessions[$_].Substring(39,9).Trim() | |
$temp.State = $sessions[$_].Substring(48,8).Trim() | |
$temp.Type = $sessions[$_].Substring(56,12).Trim() | |
$temp.Device = $sessions[$_].Substring(68).Trim() | |
$report += $temp | |
} | |
} | |
} | |
End { | |
$report | |
} | |
} #End Function Get-ComputerSessions | |
#<<< End Of Function List >>> | |
# Start of script work ############################################################################ | |
$DebugPreference = 'SilentlyContinue' #SilentlyContinue|Continue | |
$LoggedOnUsers = Get-ComputerSessions -computer localhost | |
$Counter = 0 | |
$LoggedOnUsers | ForEach-Object {If ($_.Username) | |
{$User = $_.Username | |
Write-Debug "`$_ is $User" | |
$objUser = New-Object System.Security.Principal.NTAccount("$User") | |
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier]) | |
Write-Debug "`$strSID is $strSID.Value" | |
$SID = $strSID.Value | |
$objSID = New-Object System.Security.Principal.SecurityIdentifier ("$SID") | |
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) | |
Write-Debug "`$objUser is $objUser.Value" | |
$LoggedOnUsers[$Counter].Username = $objUser.Value} | |
$Counter++} | |
Write-Debug 'Loading up array with SIDs.' | |
$SIDArray = @() | |
$RegistryDataArray = Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' | |
Foreach ($Item in $RegistryDataArray) | |
{$SID = $Item.Name -replace "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\" | |
Write-Debug "SID data found in registry: $SID." | |
$SIDArray += "$SID"} | |
Write-Debug 'Removing junk SIDs from the array.' | |
$RemoveKnownSIDArray = 'S-1-5-18','S-1-5-19','S-1-5-20' | |
Foreach ($Item in $RemoveKnownSIDArray) | |
{Write-Debug "Removing junk SID $Item." | |
$SIDArray = $SIDArray | Where-Object {$_ -ne "$Item"}} | |
Write-Debug 'Fetching user names from SIDs and checking for session.' | |
$SIDAndUserArray = @() | |
$LeadingZero = ([string]$SIDArray.Count).Length | |
$UniqueID = 0 | |
Foreach ($Item in $SIDArray) | |
{$UniqueID ++ | |
$objSID = New-Object System.Security.Principal.SecurityIdentifier ("$Item") | |
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) | |
If ($LoggedOnUsers.Username -contains $objUser) | |
{$SessionFound = 'Yes'} | |
Else{$SessionFound = 'No'} | |
If ($([Security.Principal.WindowsIdentity]::GetCurrent().Name) -eq $objUser) | |
{$SessionFound = 'Yes'} | |
$SIDAndUserArray += @{ID="$(([string]$UniqueID).PadLeft($LeadingZero,'0'))";User="$objUser"; SID="$Item"; "ActiveSession"="$SessionFound"} | |
Write-Debug "Translating SID:$objSID to $objUser. Active: $SessionFound."} | |
Write-Debug 'Gathering App-V packages from current directory.' | |
$PackageArray = Get-ChildItem -Filter *.appv | |
If ($PackageArray.count -eq 0) | |
{Write-Warning 'No App-V packages detected to process.'} | |
Else{Write-Output 'This will user publish the following App-V packages:' | |
$PackageAndUserConfigArray = @() | |
$PackageArray | foreach {Write-Debug "Working on $($_.Name)" | |
If (Test-path ($_.BaseName + '_DeploymentConfig.xml')) | |
{Write-Debug 'XML found.' | |
$DeploymentConfigXMLCheck = 'Yes'} | |
Else{Write-Debug 'XML not found.' | |
$DeploymentConfigXMLCheck = 'No'} | |
If (Test-path ($_.BaseName + '_UserConfig.xml')) | |
{Write-Debug 'XML found.' | |
$UserConfigXMLCheck = 'Yes'} | |
Else{Write-Debug 'XML not found.' | |
$UserConfigXMLCheck = 'No'} | |
$PackageAndUserConfigArray +=@{Package="$($_.Name)";DeploymentConfigXml="$DeploymentConfigXMLCheck";UserConfigXml="$UserConfigXMLCheck"}} | |
$PackageAndUserConfigArray | ForEach-Object {New-Object PSObject -Property $_} | Format-Table -Property Package,DeploymentConfigXml,UserConfigXml | |
Write-Debug 'Showing output for user selection.' | |
#$SIDAndUserArray | ForEach-Object {New-Object PSObject -Property $_} | Format-Table -Property ID,User,SID,ActiveSession | |
$SIDAndUserArray | ForEach-Object {New-Object PSObject -Property $_} | Format-Table -Property ID,User,ActiveSession | |
If ($PackageArray.count -gt 1) {Write-Warning 'This will publish multiple App-V packages to the user.'} | |
Write-Output '' | |
Write-Output 'Publish these App-V application/s to' | |
Do {$Input = Read-Host '?' | |
If ($SIDAndUserArray[$($Input - 1)].ActiveSession -eq 'No') | |
{Write-Warning 'Invalid, user has no active session.' | |
$Input = $null}} | |
Until ($Input -gt 0 -and $Input -le $SIDAndUserArray.Count) | |
$FilteredSIDAndUserArray = $SIDAndUserArray[$($Input - 1)] | |
$DisplayName = ($FilteredSIDAndUserArray.User | Out-String) -replace "`n|`r" | |
$PackageAndUserConfigArray | foreach {$AppvPackage = Get-ChildItem $_.Package | |
switch ("$($_.DeploymentConfigXml),$($_.UserConfigXml)") { | |
'Yes,No' {Write-Debug "Publishing $($AppvPackage.BaseName) with Deployment Configuration XML." | |
$PackageDeploymentConfig = $AppvPackage.BaseName + '_DeploymentConfig.xml' | |
Add-AppvClientPackage -Path $AppvPackage -DynamicDeploymentConfiguration $PackageDeploymentConfig | Publish-AppvClientPackage -UserSID $FilteredSIDAndUserArray.SID -DynamicUserConfigurationType UseDeploymentConfiguration} | |
'No,Yes' {Write-Debug "Publishing $($AppvPackage.BaseName) with User Configuration XML." | |
$PackageUserConfig = $AppvPackage.BaseName + '_UserConfig.xml' | |
Add-AppvClientPackage -Path $AppvPackage | Publish-AppvClientPackage -UserSID $FilteredSIDAndUserArray.SID -DynamicUserConfigurationPath $PackageUserConfig} | |
'Yes,Yes' {Write-Debug "Publishing $($AppvPackage.BaseName) with Deployment and User Configuration XML." | |
$DynamicConfigurationWarning = $true | |
$PackageDeploymentConfig = $AppvPackage.BaseName + '_DeploymentConfig.xml' | |
$PackageUserConfig = $AppvPackage.BaseName + '_UserConfig.xml' | |
Add-AppvClientPackage -Path $AppvPackage -DynamicDeploymentConfiguration $PackageDeploymentConfig | Publish-AppvClientPackage -UserSID $FilteredSIDAndUserArray.SID -DynamicUserConfigurationPath $PackageUserConfig} | |
'No,No' {Write-Debug "Publishing $($AppvPackage.BaseName) without any XML configurations." | |
Add-AppvClientPackage -Path $AppvPackage | Publish-AppvClientPackage -UserSID $FilteredSIDAndUserArray.SID}}} | |
If ($DynamicConfigurationWarning) { | |
Write-Warning 'Detected Deployment and User Configuration XML for a package.' | |
Write-Warning 'Note, User Configuration overrides Deployment Configuration, and Deployment Configuration overrides Manifest.'}} | |
#<<< End of script work >>> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment