Skip to content

Instantly share code, notes, and snippets.

@dmidlo
Last active August 10, 2024 04:40
Show Gist options
  • Save dmidlo/628e0238e412d8751b6524df6a88c588 to your computer and use it in GitHub Desktop.
Save dmidlo/628e0238e412d8751b6524df6a88c588 to your computer and use it in GitHub Desktop.
resume_session.ps1
## ScriptName: last_session.ps1
## author: David Midlo (dmidlo@gmail.com)
##
## Purpose: This PowerShell script is designed as a proof of concept for resuming a long-running
## process in a script that processes user accounts from Active Directory. The script stores progress
## in a file (`USERS.clixml`) so that it can resume from where it left off if interrupted, avoiding the
## need to restart from the beginning. This is particularly useful for environments
## where processing large numbers of user accounts may take significant time.
##
## Disclaimer: No warranty and all that! This is a proof of concept script only! There is no
## error handling or anything that would potentially obscure how this operation is functioning.
## (Except for "write-progress" which is vital to not going insane while waiting for hours for
## a process to complete.)
##
## ### Key Components:
## 1. **Initialization:**
## - Imports the Active Directory module as a proxy example for any long-list of work to be done.
## - Clears any previous session variables.
## - Defines the organizational unit (OU) to search for users within Active Directory.
## - Initializes two hash tables:
## - `$ImportedUserHash`: Stores users processed in previous runs.
## - `$CurrentSessionUserHash`: Tracks users processed in the current session.
##
## 2. **Import Previous Run Data:**
## - Attempts to import previously processed users from the `USERS.clixml` file.
## If the file is not found, it handles the error and continues.
##
## 3. **Fetch Users:**
## - Retrieves a list of users from Active Directory based on the specified OU.
##
## 4. **Progress Tracking:**
## - Counts the number of users retrieved and the number already processed from previous runs.
## - Displays this information to the host.
##
## 5. **Processing Users:**
## - Iterates over each user retrieved from Active Directory.
## - If the user was processed in a previous run, it skips to the next user and logs this.
## - If the user has not been processed, it:
## - Waits for 3 seconds (as a placeholder for actual processing).
## - Adds the user to the `$ImportedUserHash` hash table.
## - Exports the updated hash table to `USERS.clixml`.
## - Logs the processing of the user.
##
## 6. **Progress Bar:**
## - Updates a progress bar with the percentage of users processed and the current user being processed.
##
#######################################################################################
## clean up the variables for consecutive runs.
Import-Module activedirectory
Clear-Host
$user = $null
$users = $null
$ClixmlUsers = $null
$rootDN = $null
$ImportedUserHash = $null
$CurrentSessionUserHash = $null
#######################################################################################
## Define the OU
$rootDN = "OU=Users,DC=your,DC=com"
## Initilize HashTables $importeduserhash is the datasource, $CurrentSessionUserHash is a post-run diagnostics variable
$ImportedUserHash = @{}
$CurrentSessionUserHash = @{}
## Import Previous Runs
try {
$ErrorActionPreference = "Stop"
$ImportedUserHash = Import-Clixml .\USERS.clixml
}
catch
{
# Disregard File Not Found error as we will be creating USERS.clixml if doesn't already exist.
if ($_.Exception.message -notmatch "Could not find file") {
throw $_
}
}
## Get List of Users From Active Directory
$Users = @(Get-ADUser -filter * -SearchScope subtree -SearchBase "$rootDN" -Properties sAMAccountName,distinguishedName,homedirectory)
## Setup Variables for Write-Progress
$a = $users.Count
$b = $ImportedUserHash.count
## Notify Host of Current Progress Numbers
write-host "imported completed user count is:" $b
write-host "Active Directory user count is:" $a
## Begin Labor Loop
foreach($user in $Users){
## Check to see if User was completed in a previous run
if($ImportedUserHash.Contains($user.SamAccountName)){
## Notify Host that user has already been run in a previous session
Write-Host $user.SamAccountName "completed in previous session" -ForegroundColor Yellow
## Add to diagnostics variable with value set at "imported from previous session.
$CurrentSessionUserHash.add($user.SamAccountName,"Imported From Previous Session")
}
## If user has not been run previously, take action now
Else{
## wait just to give the script something to do to waste time for a demo
## This is where you would actually add your functional work to be done.
Start-Sleep -Seconds 3
## add user completed user to hashtable for export. This should always be the last functinal step in the foreach...
$ImportedUserHash.add($user.SamAccountName,$user.DistinguishedName)
## Export hashtable to clixml. I chose clixml instead of csv for two reasons; one, it imports as the variable as it was
## exported as. Two, it will be less likely to be deleted by some other admin.
$ImportedUserHash | Export-Clixml .\USERS.clixml
## add user to diagnostics variable with value set to "current session"
$CurrentSessionUserHash.add($user.SamAccountName,"Current Session")
## notify host things went well
write-host $user.sAMAccountName "has been added to User Hashtable"-ForegroundColor Green
## +1 to the write-progress count
$b++
}
## percent of whole calculator for write-progress
$c = ($b / $a) * 100
## update progress bar with current statistics.
write-progress -activity Updating -status 'Progress->' -percentcomplete $c -currentOperation "Profiles Completed: $b of $a Percent Complete: $c Current Accout: $user."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment