PowerShell: Execute as System Elevated Session with a Domain Administrator account

Part 1: Relaunch script in the context of Elevated System privileges:

############# Ensure that Program executes in the context of a Local System Administrator ################
# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$currentUser=$myWindowsID.Name
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)

# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator

# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
{
# We are running "as Administrator" - so change the title and background color to indicate this
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
$Host.UI.RawUI.BackgroundColor = "Black"
clear-host
}
else
{
# We are not running "as Administrator" - so relaunch as administrator

# Create a new process object that starts PowerShell
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";

# Specify the current script path and name as a parameter
$newProcess.Arguments = $myInvocation.MyCommand.Definition;

# Indicate that the process should be elevated
$newProcess.Verb = "runas";

# Start the new process
[System.Diagnostics.Process]::Start($newProcess);

# Exit from the current, unelevated, process
exit
}

function validateCurrentAccountAsDomainAdmin{
if((whoami /groups) -match 'domain admins'){
#"This account is a Domain Admins member";
return $True;
}else{
#"This account is NOT a Domain Admins member";
return $False;
}
}

Write-Host -NoNewLine "Running as $currentUser in context of Elevated System Permissions..."
Write-Host "$currentUser $(if(validateCurrentAccountAsDomainAdmin){"is"}else{"not"}) a Domain Admin."
##########################################################################################################

############# Ensure that Program executes in the context of a Domain Administrator ######################

Part 2: Obtain domain admin $CRED for subsequent Invoke-Command operations:

############# Ensure that Program executes in the context of a Domain Administrator ######################

# This function is will export a global variable $domainAdminCred of a Domain Administrator account
Function getDomainAdminCred{

# Add pre-requisites and obtain list of domain admins
if (!(Get-Module ActiveDirectory)){
Import-Module ServerManager;
Add-WindowsFeature RSAT-AD-PowerShell;
Import-Module ActiveDirectory;
}

# Set domain variables
$currentUser=[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$userDomain=$env:USERDOMAIN
$domainObject = "LDAP://" + $env:userdnsdomain
$domainAdmins=Get-ADGroupMember -Identity "Domain Admins" -Recursive | %{Get-ADUser -Identity $_.distinguishedName} | Where-Object {$_.Enabled -eq $True}|%{"$userDomain\$($_.SamAccountName)"}

# Check whether a given username matches the list of Domain Admins
function validateDomainAdminMembership{
param (
[string]$username=$currentUser
)
if($domainadmins|?{$_ -eq $username}){
Write-Host "$username is a Domain Admin";
return $True;
}else{
Write-Host "$username not a Domain Admin.";
return $False;
}
}

function testCredential{
param (
[string]$username=$currentUser,
$encryptedPassword=$currentUserPassword
)
$plaintextPassword = (New-Object System.Management.Automation.PSCredential 'N/A',$encryptedPassword).GetNetworkCredential().Password
$domainBindTest = (New-Object System.DirectoryServices.DirectoryEntry($domainObject,$username,$plaintextPassword)).DistinguishedName
if ($domainBindTest){return $True;} else{Return $False;}
}

function validateDomainAdminCred{
$global:domainAdminCred=$False;

function loopUntilCred{
# Get the domain admin account name
do {
$newID=Read-Host -Prompt 'Input a domain admin username'
if (!($newID -match $userDomain)){$newID="$userDomain\$newID"} # Add domain prefix to userID if input doesn't already contain such
$domainAdminMatched=validateDomainAdminMembership $newID;
} until ($domainAdminMatched)

# Get the correct password
do {
$newPassword = Read-Host -assecurestring "Please enter the password for $newID"
#$providedPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
#$providedCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $providedID,$providedPassword
$goodCredential=testCredential -username $newID -encryptedPassword $newPassword
if($goodCredential){
"Alternate Domain Admin Credential validated!";
$global:domainAdminCred=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $newID,$newPassword;
}
else{
"Password doesn't match.";
}
} until($goodCredential)
}

if (validateDomainAdminMembership){
$currentUserPassword=Read-Host -assecurestring "Please enter the current user's password";
if(testCredential -encryptedPassword $currentUserPassword){
"Domain Admin cred with current account has been validated!";
$global:domainAdminCred=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $currentUser,$currentUserPassword;
}else{loopUntilCred;}
}else{
loopUntilCred;
}
}
validateDomainAdminCred;
}

function computerIsDomainJoined{
if ((gwmi win32_computersystem).partofdomain -eq $true) {
write-host -fore green "$ENV:computername is domain joined!"
return $true;
} else {
write-host -fore red "$ENV:computername is on a workgroup!"
return $false;
}
}

if (computerIsDomainJoined){
getDomainAdminCred;
}else{"This computer is not joined to a domain. Thus no Domain Admin credentials are expected."}
##########################################################################################################

Leave a Reply

Your email address will not be published. Required fields are marked *