Posted On October 12, 2019

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

kimconnect 0 comments
blog.KimConnect.com >> Codes >> 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 *

Related Post

PowerShell: Windows 2016 Pristine Image

Desired Output Windows Server deployment should be made as seamless and efficient as possible. Here's…

An Exercise in Discover Whether an Active Directory Account Has RDP Access to Windows Bastion Hosts

Check Computers: $computernames='RDPSERVER01','RDPSERVER02','RDPSERVER03' invoke-command -computername $computernames {get-localgroupmember 'remote desktop users'}|select PSComputername,Name # Sample output PS…

PowerShell: Kill Processes Remotely

# This function requires 2 parameters: -computerName and -processName function killRemoteProcess{ [cmdletbinding()] param( [string]$computerName=$env:COMPUTERNAME, [parameter(Mandatory=$true)]…
Other project: DragonCoin.com