Skip to content

Commit

Permalink
Merge pull request #573 from TheJumpCloud/fix/NB-11998-windows-app-la…
Browse files Browse the repository at this point in the history
…unches-after-install

NB-11998: Windows App Launches After Install
jworkmanjc authored Jun 18, 2024
2 parents b296458 + de72aa0 commit b21912a
Showing 2 changed files with 7 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#### Name


Windows - Install JumpCloud Password Manager App | v1.2 JCCG
Windows - Install JumpCloud Password Manager App | v1.3 JCCG


#### commandType
@@ -12,7 +12,7 @@ windows

```
# Set $LaunchPasswordManager to $false ON LINE 63 if you do not wish to launch the password manger after installation
# Set $LaunchPasswordManager to $false ON LINE 69 if you do not wish to launch the password manger after installation
# Get the current logged on User
$loggedUser = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty UserName
@@ -68,18 +68,10 @@ $Command = {
$loggedOnUserProfileImagePath = Get-ItemPropertyValue -Path $registryPath -Name 'ProfileImagePath'
$LaunchPasswordManager = $true
$installerTempLocation = "$loggedOnUserProfileImagePath\AppData\Local\Temp\JumpCloud-Password-Manager-latest.exe"
. $installerTempLocation
if ($LaunchPasswordManager -eq $true) {
while (!(Test-Path "$loggedOnUserProfileImagePath\AppData\Local\jcpwm\JumpCloud Password Manager.exe")) {
Start-Sleep 10
}
try {
. "$loggedOnUserProfileImagePath\AppData\Local\jcpwm\JumpCloud Password Manager.exe"
} catch {
throw $_.Exception.Message
}
if ($LaunchPasswordManager -eq $false) {
$env:QUIT_PWM_AFTER_INITIAL_INSTALL="true"
}
. $installerTempLocation
}
$Source = @'
4 changes: 2 additions & 2 deletions PowerShell/JumpCloud Commands Gallery/commands.json
Original file line number Diff line number Diff line change
@@ -329,9 +329,9 @@
"description": "This command will download and install the CrowdStrike Falcon Agent to the device if it isn't already installed. The command will leverage CrowdStrike's API to find and download the latest version of the Falcon Agent onto the local machine.\n\nFollow the instructions from the [Installing the CrowdStrike Falcon Agent KB](https://support.jumpcloud.com/s/article/Installing-the-Crowdstrike-Falcon-Agent#InstallWindows)\n\nIn order to use this command:\n\n1. Create a CrowdStrike API Client with the \"SENSOR DOWNLOAD\" Read scope and make note of the ClientID and ClientSecret Refer to CrowdStrike's article [Getting Access to the CrowdStrike API](https://www.crowdstrike.com/blog/tech-center/get-access-falcon-apis/) for further information\n2. Set the 3 variables (CSBaseAddress, CSClientID, CSClientSecret) to their respective values for your CrowdStrike API Client\n 1. If you have Require Token enabled for your CrowdStrike org, set the CSInstallToken variable with your installation token\n3. Extend the command timeout to a value that makes sense in your environment. The suggested command timeout for an environment with average network speeds on devices with average computing power is 10 minutes. Note that the command may timeout with a 124 error code in the command result window if not extended, but the script will continue to run."
},
{
"name": "Windows - Install JumpCloud Password Manager App | v1.2 JCCG",
"name": "Windows - Install JumpCloud Password Manager App | v1.3 JCCG",
"type": "windows",
"command": "# Set $LaunchPasswordManager to $false ON LINE 63 if you do not wish to launch the password manger after installation\n\n# Get the current logged on User\n$loggedUser = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty UserName\n$loggedUser = $loggedUser -replace '.*\\\\'\n\n# Construct the Registry path using the user's SID\n$userSID = (New-Object System.Security.Principal.NTAccount($loggedUser)).Translate([System.Security.Principal.SecurityIdentifier]).Value\n$registryPath = \"HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\$userSID\"\n\n# Get the ProfileImagePath value from the Registry\n$loggedOnUserProfileImagePath = Get-ItemPropertyValue -Path $registryPath -Name 'ProfileImagePath'\nWrite-Output \"Logged On User Profile Path: $loggedOnUserProfileImagePath\"\n\n\n$installerURL = 'https://cdn.pwm.jumpcloud.com/DA/release/JumpCloud-Password-Manager-latest.exe'\nif (Test-Path \"$loggedOnUserProfileImagePath\\AppData\\Local\\Temp\" ) {\n\n $installerTempLocation = \"$loggedOnUserProfileImagePath\\AppData\\Local\\Temp\\JumpCloud-Password-Manager-latest.exe\"\n Write-Output \"Installer Location: $installerTempLocation\"\n}\nelse {\n Write-Output \"Unable to determine user profile folder\"\n Exit 1\n}\n\nWrite-Output 'Testing if Password Manager installer is downloaded'\n\nif (-not(Test-Path -Path $installerTempLocation -PathType Leaf)) {\n try {\n Write-Output 'Downloading Password Manager installer now.'\n try {\n Invoke-WebRequest -Uri $installerURL -OutFile $installerTempLocation\n } catch {\n Write-Error \"Unable to download Password Manager installer to $InstallerTempLocation.\"\n exit 1\n }\n Write-Output 'Finished downloading Password Manager installer.'\n } catch {\n throw $_.Exception.Message\n }\n}\n\nWrite-Output 'Installing Password Manager now, this may take a few minutes.'\n\n$Command = {\n # Get the current user's SID (Security Identifier)\n $loggedUser = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty UserName\n $loggedUser = $loggedUser -replace '.*\\\\'\n\n # Construct the Registry path using the user's SID\n $userSID = (New-Object System.Security.Principal.NTAccount($loggedUser)).Translate([System.Security.Principal.SecurityIdentifier]).Value\n $registryPath = \"HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\$userSID\"\n $loggedOnUserProfileImagePath = Get-ItemPropertyValue -Path $registryPath -Name 'ProfileImagePath'\n $LaunchPasswordManager = $true\n $installerTempLocation = \"$loggedOnUserProfileImagePath\\AppData\\Local\\Temp\\JumpCloud-Password-Manager-latest.exe\"\n . $installerTempLocation\n if ($LaunchPasswordManager -eq $true) {\n while (!(Test-Path \"$loggedOnUserProfileImagePath\\AppData\\Local\\jcpwm\\JumpCloud Password Manager.exe\")) {\n Start-Sleep 10\n }\n try {\n . \"$loggedOnUserProfileImagePath\\AppData\\Local\\jcpwm\\JumpCloud Password Manager.exe\"\n\n } catch {\n throw $_.Exception.Message\n }\n }\n}\n\n$Source = @'\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace murrayju.ProcessExtensions\n{\n public static class ProcessExtensions\n {\n #region Win32 Constants\n\n private const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;\n private const int CREATE_NO_WINDOW = 0x08000000;\n\n private const int CREATE_NEW_CONSOLE = 0x00000010;\n\n private const uint INVALID_SESSION_ID = 0xFFFFFFFF;\n private static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;\n\n #endregion\n\n #region DllImports\n\n [DllImport(\"advapi32.dll\", EntryPoint = \"CreateProcessAsUser\", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]\n private static extern bool CreateProcessAsUser(\n IntPtr hToken,\n String lpApplicationName,\n String lpCommandLine,\n IntPtr lpProcessAttributes,\n IntPtr lpThreadAttributes,\n bool bInheritHandle,\n uint dwCreationFlags,\n IntPtr lpEnvironment,\n String lpCurrentDirectory,\n ref STARTUPINFO lpStartupInfo,\n out PROCESS_INFORMATION lpProcessInformation);\n\n [DllImport(\"advapi32.dll\", EntryPoint = \"DuplicateTokenEx\")]\n private static extern bool DuplicateTokenEx(\n IntPtr ExistingTokenHandle,\n uint dwDesiredAccess,\n IntPtr lpThreadAttributes,\n int TokenType,\n int ImpersonationLevel,\n ref IntPtr DuplicateTokenHandle);\n\n [DllImport(\"userenv.dll\", SetLastError = true)]\n private static extern bool CreateEnvironmentBlock(ref IntPtr lpEnvironment, IntPtr hToken, bool bInherit);\n\n [DllImport(\"userenv.dll\", SetLastError = true)]\n [return: MarshalAs(UnmanagedType.Bool)]\n private static extern bool DestroyEnvironmentBlock(IntPtr lpEnvironment);\n\n [DllImport(\"kernel32.dll\", SetLastError = true)]\n private static extern bool CloseHandle(IntPtr hSnapshot);\n\n [DllImport(\"kernel32.dll\")]\n private static extern uint WTSGetActiveConsoleSessionId();\n\n [DllImport(\"Wtsapi32.dll\")]\n private static extern uint WTSQueryUserToken(uint SessionId, ref IntPtr phToken);\n\n [DllImport(\"wtsapi32.dll\", SetLastError = true)]\n private static extern int WTSEnumerateSessions(\n IntPtr hServer,\n int Reserved,\n int Version,\n ref IntPtr ppSessionInfo,\n ref int pCount);\n\n #endregion\n\n #region Win32 Structs\n\n private enum SW\n {\n SW_HIDE = 0,\n SW_SHOWNORMAL = 1,\n SW_NORMAL = 1,\n SW_SHOWMINIMIZED = 2,\n SW_SHOWMAXIMIZED = 3,\n SW_MAXIMIZE = 3,\n SW_SHOWNOACTIVATE = 4,\n SW_SHOW = 5,\n SW_MINIMIZE = 6,\n SW_SHOWMINNOACTIVE = 7,\n SW_SHOWNA = 8,\n SW_RESTORE = 9,\n SW_SHOWDEFAULT = 10,\n SW_MAX = 10\n }\n\n private enum WTS_CONNECTSTATE_CLASS\n {\n WTSActive,\n WTSConnected,\n WTSConnectQuery,\n WTSShadow,\n WTSDisconnected,\n WTSIdle,\n WTSListen,\n WTSReset,\n WTSDown,\n WTSInit\n }\n\n [StructLayout(LayoutKind.Sequential)]\n private struct PROCESS_INFORMATION\n {\n public IntPtr hProcess;\n public IntPtr hThread;\n public uint dwProcessId;\n public uint dwThreadId;\n }\n\n private enum SECURITY_IMPERSONATION_LEVEL\n {\n SecurityAnonymous = 0,\n SecurityIdentification = 1,\n SecurityImpersonation = 2,\n SecurityDelegation = 3,\n }\n\n [StructLayout(LayoutKind.Sequential)]\n private struct STARTUPINFO\n {\n public int cb;\n public String lpReserved;\n public String lpDesktop;\n public String lpTitle;\n public uint dwX;\n public uint dwY;\n public uint dwXSize;\n public uint dwYSize;\n public uint dwXCountChars;\n public uint dwYCountChars;\n public uint dwFillAttribute;\n public uint dwFlags;\n public short wShowWindow;\n public short cbReserved2;\n public IntPtr lpReserved2;\n public IntPtr hStdInput;\n public IntPtr hStdOutput;\n public IntPtr hStdError;\n }\n\n private enum TOKEN_TYPE\n {\n TokenPrimary = 1,\n TokenImpersonation = 2\n }\n\n [StructLayout(LayoutKind.Sequential)]\n private struct WTS_SESSION_INFO\n {\n public readonly UInt32 SessionID;\n\n [MarshalAs(UnmanagedType.LPStr)]\n public readonly String pWinStationName;\n\n public readonly WTS_CONNECTSTATE_CLASS State;\n }\n\n #endregion\n\n // Gets the user token from the currently active session\n private static bool GetSessionUserToken(ref IntPtr phUserToken)\n {\n var bResult = false;\n var hImpersonationToken = IntPtr.Zero;\n var activeSessionId = INVALID_SESSION_ID;\n var pSessionInfo = IntPtr.Zero;\n var sessionCount = 0;\n\n // Get a handle to the user access token for the current active session.\n if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, ref pSessionInfo, ref sessionCount) != 0)\n {\n var arrayElementSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));\n var current = pSessionInfo;\n\n for (var i = 0; i < sessionCount; i++)\n {\n var si = (WTS_SESSION_INFO)Marshal.PtrToStructure((IntPtr)current, typeof(WTS_SESSION_INFO));\n current += arrayElementSize;\n\n if (si.State == WTS_CONNECTSTATE_CLASS.WTSActive)\n {\n activeSessionId = si.SessionID;\n }\n }\n }\n\n // If enumerating did not work, fall back to the old method\n if (activeSessionId == INVALID_SESSION_ID)\n {\n activeSessionId = WTSGetActiveConsoleSessionId();\n }\n\n if (WTSQueryUserToken(activeSessionId, ref hImpersonationToken) != 0)\n {\n // Convert the impersonation token to a primary token\n bResult = DuplicateTokenEx(hImpersonationToken, 0, IntPtr.Zero,\n (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, (int)TOKEN_TYPE.TokenPrimary,\n ref phUserToken);\n\n CloseHandle(hImpersonationToken);\n }\n\n return bResult;\n }\n\n public static bool StartProcessAsCurrentUser(string appPath, string cmdLine = null, string workDir = null, bool visible = true)\n {\n var hUserToken = IntPtr.Zero;\n var startInfo = new STARTUPINFO();\n var procInfo = new PROCESS_INFORMATION();\n var pEnv = IntPtr.Zero;\n int iResultOfCreateProcessAsUser;\n\n startInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));\n\n try\n {\n if (!GetSessionUserToken(ref hUserToken))\n {\n throw new Exception(\"StartProcessAsCurrentUser: GetSessionUserToken failed.\");\n }\n\n uint dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | (uint)(visible ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW);\n startInfo.wShowWindow = (short)(visible ? SW.SW_SHOW : SW.SW_HIDE);\n startInfo.lpDesktop = \"winsta0\\\\default\";\n\n if (!CreateEnvironmentBlock(ref pEnv, hUserToken, false))\n {\n throw new Exception(\"StartProcessAsCurrentUser: CreateEnvironmentBlock failed.\");\n }\n\n if (!CreateProcessAsUser(hUserToken,\n appPath, // Application Name\n cmdLine, // Command Line\n IntPtr.Zero,\n IntPtr.Zero,\n false,\n dwCreationFlags,\n pEnv,\n workDir, // Working directory\n ref startInfo,\n out procInfo))\n {\n throw new Exception(\"StartProcessAsCurrentUser: CreateProcessAsUser failed.\\n\");\n }\n\n iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error();\n }\n finally\n {\n CloseHandle(hUserToken);\n if (pEnv != IntPtr.Zero)\n {\n DestroyEnvironmentBlock(pEnv);\n }\n CloseHandle(procInfo.hThread);\n CloseHandle(procInfo.hProcess);\n }\n return true;\n }\n }\n}\n\n\n'@\n\nAdd-Type -ReferencedAssemblies 'System', 'System.Runtime.InteropServices' -TypeDefinition $Source -Language CSharp\n$ApplicationPath = 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe'\n\n$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)\n$encodedCommand = [Convert]::ToBase64String($bytes)\n$Arguments = '-NoLogo -NonInteractive -ExecutionPolicy ByPass -WindowStyle Hidden -encodedCommand ' + $encodedCommand\n[murrayju.ProcessExtensions.ProcessExtensions]::StartProcessAsCurrentUser($ApplicationPath, $Arguments)",
"command": "# Set $LaunchPasswordManager to $false ON LINE 69 if you do not wish to launch the password manger after installation\n\n# Get the current logged on User\n$loggedUser = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty UserName\n$loggedUser = $loggedUser -replace '.*\\\\'\n\n# Construct the Registry path using the user's SID\n$userSID = (New-Object System.Security.Principal.NTAccount($loggedUser)).Translate([System.Security.Principal.SecurityIdentifier]).Value\n$registryPath = \"HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\$userSID\"\n\n# Get the ProfileImagePath value from the Registry\n$loggedOnUserProfileImagePath = Get-ItemPropertyValue -Path $registryPath -Name 'ProfileImagePath'\nWrite-Output \"Logged On User Profile Path: $loggedOnUserProfileImagePath\"\n\n\n$installerURL = 'https://cdn.pwm.jumpcloud.com/DA/release/JumpCloud-Password-Manager-latest.exe'\nif (Test-Path \"$loggedOnUserProfileImagePath\\AppData\\Local\\Temp\" ) {\n\n $installerTempLocation = \"$loggedOnUserProfileImagePath\\AppData\\Local\\Temp\\JumpCloud-Password-Manager-latest.exe\"\n Write-Output \"Installer Location: $installerTempLocation\"\n}\nelse {\n Write-Output \"Unable to determine user profile folder\"\n Exit 1\n}\n\nWrite-Output 'Testing if Password Manager installer is downloaded'\n\nif (-not(Test-Path -Path $installerTempLocation -PathType Leaf)) {\n try {\n Write-Output 'Downloading Password Manager installer now.'\n try {\n Invoke-WebRequest -Uri $installerURL -OutFile $installerTempLocation\n } catch {\n Write-Error \"Unable to download Password Manager installer to $InstallerTempLocation.\"\n exit 1\n }\n Write-Output 'Finished downloading Password Manager installer.'\n } catch {\n throw $_.Exception.Message\n }\n}\n\nWrite-Output 'Installing Password Manager now, this may take a few minutes.'\n\n$Command = {\n # Get the current user's SID (Security Identifier)\n $loggedUser = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty UserName\n $loggedUser = $loggedUser -replace '.*\\\\'\n\n # Construct the Registry path using the user's SID\n $userSID = (New-Object System.Security.Principal.NTAccount($loggedUser)).Translate([System.Security.Principal.SecurityIdentifier]).Value\n $registryPath = \"HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\$userSID\"\n $loggedOnUserProfileImagePath = Get-ItemPropertyValue -Path $registryPath -Name 'ProfileImagePath'\n $LaunchPasswordManager = $true\n $installerTempLocation = \"$loggedOnUserProfileImagePath\\AppData\\Local\\Temp\\JumpCloud-Password-Manager-latest.exe\"\n if ($LaunchPasswordManager -eq $false) {\n $env:QUIT_PWM_AFTER_INITIAL_INSTALL=\"true\"\n }\n . $installerTempLocation\n}\n\n$Source = @'\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace murrayju.ProcessExtensions\n{\n public static class ProcessExtensions\n {\n #region Win32 Constants\n\n private const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;\n private const int CREATE_NO_WINDOW = 0x08000000;\n\n private const int CREATE_NEW_CONSOLE = 0x00000010;\n\n private const uint INVALID_SESSION_ID = 0xFFFFFFFF;\n private static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;\n\n #endregion\n\n #region DllImports\n\n [DllImport(\"advapi32.dll\", EntryPoint = \"CreateProcessAsUser\", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]\n private static extern bool CreateProcessAsUser(\n IntPtr hToken,\n String lpApplicationName,\n String lpCommandLine,\n IntPtr lpProcessAttributes,\n IntPtr lpThreadAttributes,\n bool bInheritHandle,\n uint dwCreationFlags,\n IntPtr lpEnvironment,\n String lpCurrentDirectory,\n ref STARTUPINFO lpStartupInfo,\n out PROCESS_INFORMATION lpProcessInformation);\n\n [DllImport(\"advapi32.dll\", EntryPoint = \"DuplicateTokenEx\")]\n private static extern bool DuplicateTokenEx(\n IntPtr ExistingTokenHandle,\n uint dwDesiredAccess,\n IntPtr lpThreadAttributes,\n int TokenType,\n int ImpersonationLevel,\n ref IntPtr DuplicateTokenHandle);\n\n [DllImport(\"userenv.dll\", SetLastError = true)]\n private static extern bool CreateEnvironmentBlock(ref IntPtr lpEnvironment, IntPtr hToken, bool bInherit);\n\n [DllImport(\"userenv.dll\", SetLastError = true)]\n [return: MarshalAs(UnmanagedType.Bool)]\n private static extern bool DestroyEnvironmentBlock(IntPtr lpEnvironment);\n\n [DllImport(\"kernel32.dll\", SetLastError = true)]\n private static extern bool CloseHandle(IntPtr hSnapshot);\n\n [DllImport(\"kernel32.dll\")]\n private static extern uint WTSGetActiveConsoleSessionId();\n\n [DllImport(\"Wtsapi32.dll\")]\n private static extern uint WTSQueryUserToken(uint SessionId, ref IntPtr phToken);\n\n [DllImport(\"wtsapi32.dll\", SetLastError = true)]\n private static extern int WTSEnumerateSessions(\n IntPtr hServer,\n int Reserved,\n int Version,\n ref IntPtr ppSessionInfo,\n ref int pCount);\n\n #endregion\n\n #region Win32 Structs\n\n private enum SW\n {\n SW_HIDE = 0,\n SW_SHOWNORMAL = 1,\n SW_NORMAL = 1,\n SW_SHOWMINIMIZED = 2,\n SW_SHOWMAXIMIZED = 3,\n SW_MAXIMIZE = 3,\n SW_SHOWNOACTIVATE = 4,\n SW_SHOW = 5,\n SW_MINIMIZE = 6,\n SW_SHOWMINNOACTIVE = 7,\n SW_SHOWNA = 8,\n SW_RESTORE = 9,\n SW_SHOWDEFAULT = 10,\n SW_MAX = 10\n }\n\n private enum WTS_CONNECTSTATE_CLASS\n {\n WTSActive,\n WTSConnected,\n WTSConnectQuery,\n WTSShadow,\n WTSDisconnected,\n WTSIdle,\n WTSListen,\n WTSReset,\n WTSDown,\n WTSInit\n }\n\n [StructLayout(LayoutKind.Sequential)]\n private struct PROCESS_INFORMATION\n {\n public IntPtr hProcess;\n public IntPtr hThread;\n public uint dwProcessId;\n public uint dwThreadId;\n }\n\n private enum SECURITY_IMPERSONATION_LEVEL\n {\n SecurityAnonymous = 0,\n SecurityIdentification = 1,\n SecurityImpersonation = 2,\n SecurityDelegation = 3,\n }\n\n [StructLayout(LayoutKind.Sequential)]\n private struct STARTUPINFO\n {\n public int cb;\n public String lpReserved;\n public String lpDesktop;\n public String lpTitle;\n public uint dwX;\n public uint dwY;\n public uint dwXSize;\n public uint dwYSize;\n public uint dwXCountChars;\n public uint dwYCountChars;\n public uint dwFillAttribute;\n public uint dwFlags;\n public short wShowWindow;\n public short cbReserved2;\n public IntPtr lpReserved2;\n public IntPtr hStdInput;\n public IntPtr hStdOutput;\n public IntPtr hStdError;\n }\n\n private enum TOKEN_TYPE\n {\n TokenPrimary = 1,\n TokenImpersonation = 2\n }\n\n [StructLayout(LayoutKind.Sequential)]\n private struct WTS_SESSION_INFO\n {\n public readonly UInt32 SessionID;\n\n [MarshalAs(UnmanagedType.LPStr)]\n public readonly String pWinStationName;\n\n public readonly WTS_CONNECTSTATE_CLASS State;\n }\n\n #endregion\n\n // Gets the user token from the currently active session\n private static bool GetSessionUserToken(ref IntPtr phUserToken)\n {\n var bResult = false;\n var hImpersonationToken = IntPtr.Zero;\n var activeSessionId = INVALID_SESSION_ID;\n var pSessionInfo = IntPtr.Zero;\n var sessionCount = 0;\n\n // Get a handle to the user access token for the current active session.\n if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, ref pSessionInfo, ref sessionCount) != 0)\n {\n var arrayElementSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));\n var current = pSessionInfo;\n\n for (var i = 0; i < sessionCount; i++)\n {\n var si = (WTS_SESSION_INFO)Marshal.PtrToStructure((IntPtr)current, typeof(WTS_SESSION_INFO));\n current += arrayElementSize;\n\n if (si.State == WTS_CONNECTSTATE_CLASS.WTSActive)\n {\n activeSessionId = si.SessionID;\n }\n }\n }\n\n // If enumerating did not work, fall back to the old method\n if (activeSessionId == INVALID_SESSION_ID)\n {\n activeSessionId = WTSGetActiveConsoleSessionId();\n }\n\n if (WTSQueryUserToken(activeSessionId, ref hImpersonationToken) != 0)\n {\n // Convert the impersonation token to a primary token\n bResult = DuplicateTokenEx(hImpersonationToken, 0, IntPtr.Zero,\n (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, (int)TOKEN_TYPE.TokenPrimary,\n ref phUserToken);\n\n CloseHandle(hImpersonationToken);\n }\n\n return bResult;\n }\n\n public static bool StartProcessAsCurrentUser(string appPath, string cmdLine = null, string workDir = null, bool visible = true)\n {\n var hUserToken = IntPtr.Zero;\n var startInfo = new STARTUPINFO();\n var procInfo = new PROCESS_INFORMATION();\n var pEnv = IntPtr.Zero;\n int iResultOfCreateProcessAsUser;\n\n startInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));\n\n try\n {\n if (!GetSessionUserToken(ref hUserToken))\n {\n throw new Exception(\"StartProcessAsCurrentUser: GetSessionUserToken failed.\");\n }\n\n uint dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | (uint)(visible ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW);\n startInfo.wShowWindow = (short)(visible ? SW.SW_SHOW : SW.SW_HIDE);\n startInfo.lpDesktop = \"winsta0\\\\default\";\n\n if (!CreateEnvironmentBlock(ref pEnv, hUserToken, false))\n {\n throw new Exception(\"StartProcessAsCurrentUser: CreateEnvironmentBlock failed.\");\n }\n\n if (!CreateProcessAsUser(hUserToken,\n appPath, // Application Name\n cmdLine, // Command Line\n IntPtr.Zero,\n IntPtr.Zero,\n false,\n dwCreationFlags,\n pEnv,\n workDir, // Working directory\n ref startInfo,\n out procInfo))\n {\n throw new Exception(\"StartProcessAsCurrentUser: CreateProcessAsUser failed.\\n\");\n }\n\n iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error();\n }\n finally\n {\n CloseHandle(hUserToken);\n if (pEnv != IntPtr.Zero)\n {\n DestroyEnvironmentBlock(pEnv);\n }\n CloseHandle(procInfo.hThread);\n CloseHandle(procInfo.hProcess);\n }\n return true;\n }\n }\n}\n\n\n'@\n\nAdd-Type -ReferencedAssemblies 'System', 'System.Runtime.InteropServices' -TypeDefinition $Source -Language CSharp\n$ApplicationPath = 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe'\n\n$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)\n$encodedCommand = [Convert]::ToBase64String($bytes)\n$Arguments = '-NoLogo -NonInteractive -ExecutionPolicy ByPass -WindowStyle Hidden -encodedCommand ' + $encodedCommand\n[murrayju.ProcessExtensions.ProcessExtensions]::StartProcessAsCurrentUser($ApplicationPath, $Arguments)",
"link": "https://github.com/TheJumpCloud/support/blob/master/PowerShell/JumpCloud%20Commands%20Gallery/Windows%20Commands/Windows%20-%20Install%20JumpCloud%20Password%20Manager%20App.md",
"description": "This command will download and install the JumpCloud Password Manager app to the device if it isn't already installed. On slower networks, timeouts with exit code 127 can occur. Manually setting the default timeout limit to 600 seconds may be advisable."
},

0 comments on commit b21912a

Please sign in to comment.