Something like su(1) for PowerShell and Console
August 9, 2010 1 Comment
If you have your day-to-day account configured as a limited user and not a member of the Administrators group, you have to elevate to switch users or use the runas service to do some system configuration tasks. If you already have a shell open anyway, the runas comand-line is probably what you want, but the syntax of the command is a little verbose. I have a basic su-like su for PowerShell that opens a new PowerShell session in a new Console window running with the credentials you gave to su. By default it tries to log you in as the built-in administrator account (which is disabled by default on Windows Vista/7).
su.ps1
#emulate UNIX su behavior
#start a new powershell instance with a different user account context
param( [string] $username )
function Substitute-User( [String] $username )
{
if( !$username )
{
#look up the built-in Administrator account using WMI.
#the built-in administrator has a SID that starts with S-1-5 and ends with -500.
$accts = get-wmiobject win32_useraccount
foreach( $acct in $accts )
{
if( $acct.SID -match '^S-1-5-.+-500$' )
{
$username = $acct.Caption
if( $username -match "[^\\]+$" )
{
$username = $matches[0]
}
break
}
}
}
$credential = Get-ConsoleCredential( $username )
$startinfo = new-object Diagnostics.ProcessStartInfo
$startinfo.UseShellExecute = $false
$startinfo.FileName = "$env:programfiles\Console2\Console.exe"
$startinfo.UserName = $credential.UserName
$startinfo.Password = $credential.Password
$startinfo.Arguments = "-r $pshome\powershell.exe -d `"$pwd`""
$startinfo.WorkingDirectory = $pwd
trap [ComponentModel.Win32Exception]
{
if( $_.Exception.NativeErrorCode -eq 267 )
{
write-host "$pwd is an invalid directory for $username."
write-host "Starting PowerShell in ${env:SystemRoot}\system32."
$startinfo.Arguments = "-r $pshome\powershell.exe -d ${env:SystemRoot}\system32"
$startinfo.WorkingDirectory = "${env:SystemRoot}\system32"
$null = [Diagnostics.Process]::Start( $startinfo )
}
else
{
$_.Exception.Message
}
continue
}
$null = [Diagnostics.Process]::Start( $startinfo )
}
#Generate a PSCredential object without creating a pop-up security dialog like
#the built-in get-credential cmdlet.
function Get-ConsoleCredential( [String] $username=$( read-host 'Username' ) )
{
while( !($username) )
{
$username = read-host 'Username'
}
$passwd = read-host -asSecureString 'Password'
new-object Management.Automation.PSCredential $username, $passwd
}
Substitute-User $username
Neat, didn’t know about Console 2. Sounds like the script will launch a new Console2 process, spawning a new window rather than a new tab. Somewhat defeats the purpose of using Console 2! I found another Console Emulator that could supports opening a session in a new tab if a Console Emu process already exists by virtue of researching the problem, thought I’d share.
http://superuser.com/questions/420444/console2-open-new-tab-in-existing-session-from-cmd