su__.ps1

<#PSScriptInfo
 
.VERSION 2.1
 
.GUID c4e45b4d-cc4f-4257-a443-9d5ea936ba1b
 
.AUTHOR James O'Neill
 
.COMPANYNAME Mobula Consulting Ltd
 
.COPYRIGHT
 
.TAGS su, RunAS, SecureString
 
.LICENSEURI https://opensource.org/licenses/MS-PL
 
.DESCRIPTION
 Similar to the Unix command, helps admins to start tasks as a more privileged account than the one they logged on with.
#>
 

<#
.SYNOPISIS
    Starts a process (by default another PowerShell session) as a more privileged user
.Description
    This is a script for administrators who start tasks as a user other than their normal logon.
    The script is normally named SU.PS1
    Passwords are saved as secure strings which can only be decoded by the user who saved them.
    The intention is to save a credential on the first occasion the script is run (by running as su -save)
    and reuse that credential from then on.
    The script guesses what the elevated account name should be, and if no program is specified,
    it assumes another instance of PowerShell
    This draws heavily on http://poshcode.org/1387 and originally used work of Hal Rottenberg (halr9000) as well
.Example
    su -save
    Starts an Elevated PowerShell session (PowerShell ISE if running in the ISE) and saves credentials
.Example
    su cmd.exe
    Starts the cmd as the elevated account.
.Example
    su
    Starts another copy of PowerShell (the or ISE) using the default account and saved credentials (if available)
.Example
    su notepad -user "Alex"
    Starts notepad.exe as the user "Alex" , prompting for credentials if none have been saved
#>


param (
    #The command to run if not specified this will start another copy of PowerShell
    [string]$FilePath = (Get-Process -id $PID).path ,
    #The user to run the process as: default to user's current domain name prefixed with ADM-. "SU" can be used for "local administrator"
    [string]$UserName = $env:userdomain  +"\ADM-"+ $env:UserName ,
    #if Specified the credential will be saved
    [switch]$SaveCredential ,
    #if Specified an existing credential will be deleted
    [switch]$DeleteCredential,
    #if specified load without a profile
    [switch]$NoProfile
)

#User "SU" can be a shortcut for "local administrator" even if the account has been renamed.
if ($UserName -eq    "SU")    { 
         $UserName = (Get-WmiObject -Query 'SELECT * FROM Win32_Account WHERE LocalAccount = True AND SID LIKE "S-1-5-21-%-500"').Caption
}
$credPath = Join-Path -Path:$env:UserProfile -ChildPath ($UserName -Replace "\\","_")

if     ( $DeleteCredential -and ( Test-Path -path $credPath))   { Remove-Item -Path $credPath -Force  -Verbose    }

if     ( $SaveCredential   -or !( Test-Path -path $credPath))   { #If we are overwriting the file or it doesn't exist ...
    try   { $Credential = Get-Credential -Message "Credentials for your elevated session" -Credential $UserName  }
    catch {    Write-Warning -Message $Error[0].exception.message    }
}
elseif (Test-Path -Path $credPath)                              { #If the file exists (and we aren't overwriting it)
           $Credential =  Import-Clixml -Path $credPath
 }    
if     ( -not  $Credential )                                    {#if we couldn't read the file, or if the user didn't enter one..
            Write-Warning -Message "Credential is not defined. Exiting..." ; 
            exit 1326; # 1326 Logon failure: unknown user name or bad password.
}

#Now start the program ... Check it exists, try to start in the profile directory for the elevated user, failing that run where the program is
try   { 
      $executatble = (Get-Command -CommandType Application -Name $FilePath -ErrorAction SilentlyContinue).path  | Select-Object -First 1
      if    (-not $executatble) {Write-Warning -Message "$FilePath is not recognised as the name of command"; exit 2 }
      else  {
        $workingdir = $env:UserProfile -replace $env:UserName, ($UserName -replace "^.*\\","")
        if (-not (Test-Path -Path $workingdir) ) {$workingdir = Split-Path -Path $executatble -Parent}
        $loadUserProfile = -not $NoProfile
        Start-Process -LoadUserProfile:$loadUserProfile -Credential $Credential -FilePath $executatble -WorkingDirectory $workingdir
      }
}
catch {   #if it fail to start because the credential was bad, then don't save it - and delete the saved (out of date) credential
    Write-Warning -Message $Error[0].exception.message
    if ( ($Error[0] -match "Logon failure: unknown user name or bad password") -and !$SaveCredential ) {
        if ( Test-Path -Path $credPath ) {
            Write-Warning -Message "Deleting invalid credential. Use -SaveCredential next time to save it again."
            Remove-Item -Path $credPath -Force    
            exit 1326; # Logon failure: unknown user name or bad password.
        }
    } 
}
#If we started successfully, save the credential if requested
if ( $? -and  $SaveCredential ) {Export-Clixml -InputObject $Credential -Path $credPath}