SharePoint: PowerShell Runas
Introduction
Have you ever had a SharePoint PowerShell script where you need to run a section of the script with elevated privileges (for example, under the security context of the farm service account), without being prompted to enter credential information?
You can achieve this by running the code in a script block using the Invoke-Command cmdlet. The Invoke-Command cmdlet can take a PSSession object as a parameter. Using a PSSession object, you can create a PowerShell session with a different security context (as long as you have the username and password of the different user account) by passing the alternate credentials as a PSCredential object.
It's all very easy, and here are a few examples examples.
Example
Basic PowerShell code to run a script block using alternate credentials:
#Variables to store the username and password for the alternate account
$SPFarmAccountName = "sp-dev-farm";
$FarmAccountPassword = "NotMyPswd";
#Convert the plain text password to a SecureString, required to create the PSCredential object
$FarmAccountPasswordAsSecureString = $FarmAccountPassword | ConvertTo-SecureString -Force -AsPlainText
#Create the PSCredential object using the alternate users username and password
#Note that the Domain name has been prepended to the username, using the $env:userdomain variable, which represents the current domain.
$credential = New-Object System.Management.Automation.PsCredential("$env:userdomain\$SPFarmAccountName",$FarmAccountPasswordAsSecureString)
#Create a new PowerShell session in the security context of the alternate user, using the PSCredential object we just created
$farmSvcAccSession = New-PSSession -Credential $credential;
#Write some text to the PowerShell Window, that prints the username from the current context
Write-Host "This PowerShell command is running under the current users context, $env:userdomain\$env:username" -f magenta
#Pass the PSSession object to Invoke-Command, and write some text to the PowerShell Window, that prints the username from the current context of the PSSession object (which will be the security context of the alternate user)
Invoke-Command -Session $farmSvcAccSession -Script { Write-Host "Hello, this script block is running under the security context of the SharePoint Farm Account, $env:userdomain\$env:username" -f Green; }
#Write some more text to the PowerShell Window, that shoes the security context has returned to the original user
Write-Host "And now we return to the current users context, $env:userdomain\$env:username" -f magenta
http://1.bp.blogspot.com/-2RGRF4y5_eo/U17I_rhtckI/AAAAAAAAAHk/zOWRcB0nH7k/s1600/g1.png
Run a PowerShell script block using alternate credentials, passing a parameter to the elevated session (in this case, a URL)
$waUrl = "http://portal.dev.local";
$SPFarmAccountName = "sp-dev-farm";
$FarmAccountPassword = "NotMyPswd";
$FarmAccountPasswordAsSecureString = $FarmAccountPassword | ConvertTo-SecureString -Force -AsPlainText
$credential = New-Object System.Management.Automation.PsCredential("$env:userdomain\$SPFarmAccountName",$FarmAccountPasswordAsSecureString)
$farmSvcAccSession = New-PSSession -Credential $credential;
Write-Host "This PowerShell command is running under the current users context, $env:userdomain\$env:username" -f magenta
Invoke-Command -Session $farmSvcAccSession -Script { Write-Host "Hello, this script block is running under the security context of the SharePoint Farm Account, $env:userdomain\$env:username The web URL is"$args[0] -f Green; } -Args $waUrl
Write-Host "And now we return to the current users context, $env:userdomain\$env:username" -f magenta
http://3.bp.blogspot.com/-evSz4CxYnLU/U17JHowilKI/AAAAAAAAAHs/WaUIHYQ3qEc/s1600/g2.png
Run a PowerShell script block using alternate credentials, passing a URL as a parameter to the elevated session, and then running some SharePoint commands (notice that the SharePoint PowerShell snapin needs to be loaded).
$waUrl = "http://portal.dev.local";
$SPFarmAccountName = "sp-dev-farm";
$FarmAccountPassword = "NotMyPswd";
$FarmAccountPasswordAsSecureString = $FarmAccountPassword | ConvertTo-SecureString -Force -AsPlainText
$credential = New-Object System.Management.Automation.PsCredential("$env:userdomain\$SPFarmAccountName",$FarmAccountPasswordAsSecureString)
$farmSvcAccSession = New-PSSession -Credential $credential;
Write-Host "This PowerShell command is running under the current users context, $env:userdomain\$env:username" -f magenta
Invoke-Command -Session $farmSvcAccSession -Script { Add-PSSnapin "Microsoft.SharePoint.PowerShell"; Write-Host "Hello, this script block is running under the security context of the SharePoint Farm Account, $env:userdomain\$env:username The web URL is"$args[0] -f Green; $eweb = Get-SPWeb $args[0];$eweb.SiteAdministrators | ForEach-Object {Write-Host "Removing user $_ from site administrators group." -f green;}; Write-Host "Just joking! Do you think we're crazy?!" -f yellow; } -Args $waUrl
Write-Host "And now we return to the current users context, $env:userdomain\$env:username" -f magenta
http://4.bp.blogspot.com/-5_O-a3YrgLo/U17JOmIV3UI/AAAAAAAAAH0/CVgrPPCIPg0/s1600/g3.png
See Also
References
- Original content from Matthew Yarlett's blog, PowerShell Runas