Skip to content

Instantly share code, notes, and snippets.

@phyoewaipaing
Last active November 12, 2023 12:43
Show Gist options
  • Save phyoewaipaing/eb1fa6ed1111d404d3c9c0fe747ca495 to your computer and use it in GitHub Desktop.
Save phyoewaipaing/eb1fa6ed1111d404d3c9c0fe747ca495 to your computer and use it in GitHub Desktop.
Lock up the AD user and Add to specific Domain Security Group
###############################################################################################################################################################################################################################################
## This script will lockup the domain user in a specific computer and add this user to more privileged domain group for a short time interval ( 1 min to 24 hr )
## This script must be running on the computer with RSAT tools installed or directly on a domain controller where the user running the script must be the necessary permission to change the membership of the group you want to add the user ##
## It will ask for the username and the computer name to lockup this user
## After specifying hr and min, the countdown will start
## It will release the user and remove from the privileged domain group when the countdown reaches zero
## It will do the same thing if you stop the script by pressing Ctrl+C midway
## The domain security group must already be added to local groups (eg: Administrators, Network Configuration Operators) of the client computers by GPO or other methods
## Author: Phyoe Wai Paing
## Country: Myanmar (Burma)
## v1.0 : 23.Apr.2020 : Initial Release
## v2.0 : 19.May.2020 : Can add multiple Logon Computers separated by commas
## v2.1 : 18.May.2021 : Extend the allowed duration to 3 days. Fix that multiple computers names are appended in the display output
#################################################################################################################################################################################################################################################
$GroupToAddUser = "Desktop Support Administrators" ## Change this variable to any domain security group to suite your needs unless the script is digitally signed##
## Resize the screen buffer size so that, we can update the timer digits later ##
mode 120
Write-Host -fore Yellow "[Warning]: This Script will temporarily lock up the user on specific computer and escalate the privileges by adding the user to `'$($GroupToAddUser)`' domain security group.`n"
$OK= 0; ## Will change to 1 if the user is found ##
while ($InputUserName -ne 0 -AND $OK -eq 0)
{
$InputUserName = Read-Host "Enter User Name [Press 0 to exit]";
switch ($InputUserName)
{
{ $InputUserName -match '^0$' } { Write-Host "The Script exits"; EXIT; }
## If the username contains @, then it must alos contain dot ##
{ $InputUserName -match '(^\w+\.*\w+$)(?!\w+@\w+)' } {
Try {
$UserName = (Get-ADUser -Identity $InputUserName).UserPrincipalName;
$UserName = $UserName.Split('@')[0]
Write-Host -fore green "User Name is found: $UserName";
$OK=1;
}
Catch {
Write-Host -fore red "User Name $InputUserName is not found";
}
}
## If the username contains @ (eg: user01@testdomain.local), then split and extract the username ##
{ $InputUserName -match '^\w+\.*\w+@\w+\.\w+$' } { $UserName = $InputUserName.Split('@')[0];
Try {
$UserName = (Get-ADUser -Identity $UserName).UserPrincipalName;
$UserName = $UserName.Split('@')[0]
Write-Host -fore green "User Name is found: $UserName";
$OK=1;
}
Catch {
Write-Host -fore red "User Name $InputUserName is not found";
}
}
## If the username contains backslash (eg: testdomain\user01), then split and extract the username ##
{ $InputUserName -match '^\w+\\\w+' } { $UserName = $InputUserName.Split('\')[1];
Try {
$UserName = (Get-ADUser -Identity $UserName).UserPrincipalName;
$UserName = $UserName.Split('@')[0]
Write-Host -fore green "User Name is found: $UserName";
$OK=1;
}
Catch {
Write-Host -fore red "User Name Not found: $UserName";
}
}
Default { Write-Host -fore red "User Name is invalid: $InputUserName"; }
}
}
$CompuNameArray = @(); ## Array to keep the found computer names##
## Prompt and Validate for the Computername ##
$OK=0;
while ($InputCompuName -ne 0 -AND $OK -eq 0)
{
$InputCompuNames = Read-Host "Enter Computer Name [Press 0 to exit]";
$InputCompuNames = $InputCompuNames -split ','
foreach ($InputCompuName in $InputCompuNames)
{
switch -Regex ($InputCompuName)
{
'^0$' { Write-Host "The Script exits."; EXIT; }
## accept computer name not more than 15 characters ##
'^[A-Z0-9-_]{1,15}$' {
Try {
$CurCompuName = (get-adcomputer $InputCompuName -Properties Name -EA Stop ).Name;
$CompuNameArray += $CurCompuName;
Write-Host -fore green "Computer Name is found: $CurCompuName"; $OK=1;
}
catch {
Write-Host -fore red "Computer Name is Not found: $InputCompuName";
}
}
## Check if the input value is an IP address ##
"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b"
{
Try {
## Lookup up the PTR record to find the computername, if not ok, then query from AD ##
$CurCompuName = (Resolve-DnsName -Name $InputCompuName -Type PTR -DnsOnly -NoRecursion -EA Stop).NameHost.Split('.')[0]
$CompuNameArray += $CurCompuName
Write-Host -fore green "Computer Name for $InputCompuName is found: $CurCompuName"; $OK=1;
}
catch {
try {
$CurCompuName = (Get-adcomputer -Filter 'Ipv4Address -eq $InputCompuName' -EA Stop).Name
$CompuNameArray += $CurCompuName
Write-Host -fore green "Computer Name for $InputCompuName is found: $CurCompuName"; $OK=1;
}
catch {
Write-Host -fore red "Computer Name for $InputCompuName is Not found";
}
}
}
Default
{ Write-Host -fore red "Computer Name `'$InputCompuName`' is invalid." }
}
}
}
## Create the $Duration hash table so that we can pass it to switch statement ##
$Duration = @{}
$OK = 0;
## Prompt user for hour and minutes information. It will constantly prompt if more than 24hr is entered ##
while ($OK -eq 0)
{
$Duration["Hr"] = Read-Host "`nHow many hours do you want to lock up this user?[Press x to exit, 0 for less than 1 hr]"
If ($Duration["Hr"] -eq 'x') { Write-Host "[X] is detected. The Script exits."; EXIT; }
$Duration["Min"] = Read-Host "How many minutes do you want to lock up this user?[Press x to exit]"
switch($Duration)
{
{$Duration["Hr"] -match "^[x]$" -OR $Duration["Min"] -match "^[x]$" } { Write-Host "[X] is detected. The Script exits."; EXIT; }
{$Duration["Hr"] -le 72 -AND $Duration["Min"] -eq 0 } { $DurationSeconds = ($Duration["Hr"] * 3600) + ($Duration["Min"] * 60); $OK = 1; }
{$Duration["Hr"] -le 71 -AND $Duration["Min"] -lt 60 } { $DurationSeconds = ($Duration["Hr"] * 3600) + ($Duration["Min"] * 60); $OK = 1; }
Default { Write-Host -fore yellow "You can only specify the time less than 72hr"; }
}
}
## Create the $DurationSeconds variable to compare in the next while loop section ##
$DurationSeconds = ([int]$Duration["Hr"] * 3600) + ([int]$Duration["Min"] * 60)
### If the user running the script does not have the necessary permission to modify the target user, then output the error message ###
Try {
$CompuNameArrayString = $CompuNameArray -join ',';
## Lock down the user to specific computer ##
Set-ADUser -Identity $UserName -LogonWorkstations $CompuNameArrayString -Confirm:$false
## Add the user to the specific security group (for privilege escalation) ##
Add-ADGroupMember -Identity $GroupToAddUser -Members $UserName -Confirm:$false
## Output the information with colorized computer name ##
Write-Host "`nThis windows will automatically close after user is unlocked from " -NoNewline
## Write back the computer name to the end of the previous line ##
## Move x coordinate by 66 chracters to write the Computer Name in Color ##
Write-Host -fore green $CompuNameArrayString;
Write-Host "If you want to unlock immediately, press Ctrl+C"
Write-Host "Remaining Time to unlock `'$UserName`' from computer: " -NoNewline
$origpos = $host.UI.RawUI.CursorPosition; ## Keep the current position so that the hr,min,sec digits can write back to the blank spaces in the next while loop section##
$JumpSpaces= " Hours Minutes Seconds"
Write-Host $JumpSpaces -NoNewline
$Counter=0
## Loop the 1 sec counter and match with the converted total seconds value ##
while ($Counter -le $DurationSeconds )
{
$TimeSpan = [timespan]::fromseconds($DurationSeconds - $Counter)
$CurHours = $TimeSpan.TotalHours
$CurMinutes = $TimeSpan.Minutes
$CurSeconds = $TimeSpan.Seconds
## Get the start coordindates of the line where the rotating time digits are displayed ##
$newgpos = $origpos
$newgpos.X = $origpos.X + $JumpSpaces.Length - 30 ## Move 30 characters to the left from the end of the line.
$host.UI.RawUI.CursorPosition = $newgpos
$CurHoursText = "{0:00}" -f $CurHours
Write-Host -fore yellow $CurHoursText -NoNewline
## Get the start coordindates of the line where the rotating time digits are displayed ##
$newgpos = $origpos
$newgpos.X = $origpos.X + $JumpSpaces.Length - 21 ## Move 21 characters to the left from the end of the line.
$host.UI.RawUI.CursorPosition = $newgpos
$CurMinutesText = "{0:00}" -f $CurMinutes
Write-Host -fore yellow $CurMinutesText -NoNewline
## Get the start coordindates of the line where the rotating time digits are displayed ##
$newgpos = $origpos
$newgpos.X = $origpos.X + $JumpSpaces.Length - 10 ## ## Move 10 characters to the left from the end of the line.
$host.UI.RawUI.CursorPosition = $newgpos
$CurSecondsText = "{0:00}" -f $CurSeconds
Write-Host -fore yellow $CurSecondsText
$Counter++
Start-Sleep 1;
## Capture the Ctrl+C Break ##
[Console]::TreatControlCAsInput = $True
while ($Host.UI.RawUI.KeyAvailable -and ($Key = $Host.UI.RawUI.ReadKey("AllowCtrlC,NoEcho,IncludeKeyUp")))
{
If ([Int]$Key.Character -eq 3) {
## Remove User from the specific group membership ##
Remove-ADGroupMember -Identity $GroupToAddUser -Members $UserName -Confirm:$false;
## Release the user from specific computere ##
Set-ADUser -Identity $UserName -LogonWorkstations $NULL -Confirm:$false;
Write-Host -fore DarkYellow "Ctrl+C pressed. `'$UserName`' is removed from `'$GroupToAddUser`' and unlocked from `'$($CompuNameArray -join ',')`' immediately."
exit;
}
$Host.UI.RawUI.FlushInputBuffer()
}
}
#### Actions to do when the timer reaches zero ###
## Remove User from the specific group membership ##
Remove-ADGroupMember -Identity $GroupToAddUser -Members $UserName -Confirm:$false;
## Release the user from specific computere ##
Set-ADUser -Identity $UserName -LogonWorkstations $NULL -Confirm:$false;
}
catch [Microsoft.ActiveDirectory.Management.ADException]
{
Write-Host -fore red "You do not have necessary permission to lockup the user and add into `'$($GroupToAddUser)`' group. Script Exits."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment