AutoMate Technisch Help

IAM HR Sync - Active Directory Scripts

Overzicht

Deze pagina documenteert de beschikbare PowerShell scripts voor Active Directory backup en restore operaties.

Backup-ADUsers.ps1

Doel

Maak een complete backup van alle AD user properties naar JSON files. Handig voor:

  • πŸ”„ Disaster recovery

  • πŸ“‹ Audit trail

  • πŸ§ͺ Testing changes (backup → modify → restore)

  • πŸ“Š Historical tracking

Locatie

Scripts/AD/Backup-ADUsers.ps1

Parameters

Parameter

Type

Verplicht

Default

Beschrijving

BackupPath

String

Nee

C:\AD_Backup\yyyyMMdd_HHmmss

Pad waar backup wordt opgeslagen

SearchBase

String

Nee

(leeg)

OU om te backuppen; leeg = hele domain

Server

String

Nee

$env:LOGONSERVER

Domain Controller

Gebruik

Basis (hele domain):

.\Backup-ADUsers.ps1

Specifieke OU:

.\Backup-ADUsers.ps1 -SearchBase "OU=Employees,DC=company,DC=nl"

Custom pad:

.\Backup-ADUsers.ps1 -BackupPath "D:\Backups\AD_Users"

Specifieke DC:

.\Backup-ADUsers.ps1 -Server "DC01.company.nl"

Output

Console output:

Starting AD user backup Server: DC01 Path: C:\AD_Backup\20250101_143052 Found 1245 users [1/1245] john.doe - 42 properties [2/1245] jane.smith - 38 properties [3/1245] peter.jones - 41 properties ... ======================================== Backup completed ======================================== Location: C:\AD_Backup\20250101_143052 Users: 1245 Properties: 50890 Average: 40.87 per user Restore examples: Restore complete user (default): .\Restore-ADUser.ps1 -BackupPath "C:\AD_Backup\20250101_143052" -SamAccountName "username" Restore specific properties: .\Restore-ADUser.ps1 -BackupPath "C:\AD_Backup\20250101_143052" -SamAccountName "username" -Properties "Title","Department" Preview changes (WhatIf): .\Restore-ADUser.ps1 -BackupPath "C:\AD_Backup\20250101_143052" -SamAccountName "username" -WhatIf -ShowDifferences ========================================

Backup Structuur

Per user:

C:\AD_Backup\20250101_143052\ β”œβ”€β”€ john.doe.json β”œβ”€β”€ jane.smith.json β”œβ”€β”€ peter.jones.json β”œβ”€β”€ ... └── _index.json

User JSON format:

{ "SamAccountName": "john.doe", "DistinguishedName": "CN=John Doe,OU=Employees,DC=company,DC=nl", "UserPrincipalName": "john.doe@company.nl", "ObjectGUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "BackupDate": "2025-01-01 14:30:52", "BackupServer": "DC01", "Properties": { "DisplayName": "John Doe", "GivenName": "John", "Surname": "Doe", "Title": "Senior Developer", "Department": "Engineering", "Manager": "CN=Jane Smith,OU=Managers,DC=company,DC=nl", "EmailAddress": "john.doe@company.nl", "OfficePhone": "+31 20 1234567", "MobilePhone": "+31 6 12345678", "StreetAddress": "Main Street 123", "City": "Amsterdam", "PostalCode": "1012 AB", "Country": "NL", ... } }

Index file (_index.json):

{ "BackupDate": "2025-01-01 14:30:52", "Server": "DC01", "SearchBase": "OU=Employees,DC=company,DC=nl", "TotalUsers": 1245, "AveragePropertiesPerUser": 40.87, "ExcludedProperties": [ "BadLogonCount", "ObjectGUID", "ObjectSID", ... ], "Users": [ { "SamAccountName": "john.doe", "UserPrincipalName": "john.doe@company.nl", "DisplayName": "John Doe", "DistinguishedName": "CN=John Doe,OU=Employees,DC=company,DC=nl", "Enabled": true, "ObjectGUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }, ... ] }

Excluded Properties

Sommige properties worden niet gebackupt omdat ze read-only of tijdelijk zijn:

  • Identity: ObjectGUID, ObjectSID, SID, DistinguishedName

  • Timestamps: WhenCreated, WhenChanged, LastLogonDate, pwdLastSet

  • System: ObjectClass, ObjectCategory, InstanceType, uSNCreated

  • Logon: lastLogon, lastLogonTimestamp, logonCount, badPwdCount

  • Computed: PropertyNames, PropertyCount, TokenGroups

  • Security: nTSecurityDescriptor, adminCount, userAccountControl

Volledige lijst: zie script source.

Script Code

param( [Parameter(Mandatory=$false)] [string]$BackupPath = "C:\AD_Backup\$(Get-Date -Format 'yyyyMMdd_HHmmss')", [Parameter(Mandatory=$false)] [string]$SearchBase = "", [Parameter(Mandatory=$false)] [string]$Server = $env:LOGONSERVER.Replace("\\", "") ) if (!(Get-Module -ListAvailable -Name ActiveDirectory)) { Write-Host "Error: ActiveDirectory module not found" -ForegroundColor Red Write-Host "Install with: Install-WindowsFeature RSAT-AD-PowerShell" -ForegroundColor Yellow return } Import-Module ActiveDirectory New-Item -ItemType Directory -Path $BackupPath -Force | Out-Null Write-Host "`nStarting AD user backup" -ForegroundColor Green Write-Host "Server: $Server" -ForegroundColor Cyan Write-Host "Path: $BackupPath" -ForegroundColor Cyan $excludedProperties = @( 'ObjectGUID', 'ObjectSID', 'SID', 'DistinguishedName', 'CN', 'Name', 'SamAccountName', 'WhenCreated', 'WhenChanged', 'Created', 'Modified', 'createTimeStamp', 'modifyTimeStamp', 'LastLogonDate', 'LastBadPasswordAttempt', 'accountExpires', 'lastLogoff', 'ObjectClass', 'ObjectCategory', 'DSCorePropagationData', 'InstanceType', 'uSNCreated', 'uSNChanged', 'nTSecurityDescriptor', 'lastLogon', 'lastLogonTimestamp', 'logonCount', 'LastLogon', 'badPwdCount', 'badPasswordTime', 'pwdLastSet', 'BadLogonCount', 'PropertyNames', 'PropertyCount', 'AddedProperties', 'ModifiedProperties', 'RemovedProperties', 'ProtectedFromAccidentalDeletion', 'AccountNotDelegated', 'AllowReversiblePasswordEncryption', 'CannotChangePassword', 'DoesNotRequirePreAuth', 'Enabled', 'HomedirRequired', 'LockedOut', 'MNSLogonAccount', 'PasswordExpired', 'PasswordNeverExpires', 'PasswordNotRequired', 'SmartcardLogonRequired', 'TrustedForDelegation', 'TrustedToAuthForDelegation', 'UseDESKeyOnly', 'userAccountControl', 'PrimaryGroup', 'primaryGroupID', 'adminCount', 'sAMAccountType', 'showInAdvancedViewOnly', 'codePage', 'countryCode', 'msDS-SupportedEncryptionTypes', 'msDS-ReplAttributeMetaData', 'msDS-ReplValueMetaData', 'replPropertyMetaData', 'replUpToDateVector', 'TokenGroups', 'TokenGroupsGlobalAndUniversal', 'TokenGroupsNoGCAcceptable', 'CanonicalName', 'Deleted', 'isDeleted', 'sDRightsEffective', 'msDS-User-Account-Control-Computed', 'IsCriticalSystemObject' ) $params = @{ Filter = '*' Properties = '*' Server = $Server } if ($SearchBase) { $params.SearchBase = $SearchBase Write-Host "SearchBase: $SearchBase" -ForegroundColor Cyan } $users = Get-ADUser @params $totalUsers = $users.Count $counter = 0 $totalPropertiesBackedUp = 0 Write-Host "Found $totalUsers users`n" -ForegroundColor Yellow foreach ($user in $users) { $counter++ $percentComplete = [math]::Round(($counter / $totalUsers) * 100, 2) Write-Progress -Activity "Backing up users" -Status "$($user.SamAccountName)" -PercentComplete $percentComplete $userBackup = @{ SamAccountName = $user.SamAccountName DistinguishedName = $user.DistinguishedName UserPrincipalName = $user.UserPrincipalName ObjectGUID = $user.ObjectGUID.ToString() BackupDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" BackupServer = $Server Properties = @{} } $propertiesBackedUp = 0 $user.PSObject.Properties | ForEach-Object { $propName = $_.Name $propValue = $_.Value if ($excludedProperties -notcontains $propName -and $propName -notmatch '^Property' -and $propValue -ne $null) { try { $valueToStore = $null if ($propValue -is [DateTime]) { $valueToStore = $propValue.ToString("yyyy-MM-dd HH:mm:ss") } elseif ($propValue -is [Microsoft.ActiveDirectory.Management.ADPropertyValueCollection]) { $valueToStore = @($propValue) } elseif ($propValue -is [System.Security.Principal.SecurityIdentifier]) { $valueToStore = $propValue.Value } elseif ($propValue -is [byte[]]) { $valueToStore = [Convert]::ToBase64String($propValue) } elseif ($propValue.GetType().Name -eq 'ActiveDirectorySecurity') { $valueToStore = $null } else { $valueToStore = $propValue } if ($null -ne $valueToStore) { $userBackup.Properties[$propName] = $valueToStore $propertiesBackedUp++ } } catch { Write-Host "Warning: Failed to backup property '$propName' for $($user.SamAccountName): $($_.Exception.Message)" -ForegroundColor DarkYellow } } } $totalPropertiesBackedUp += $propertiesBackedUp $safeFileName = $user.SamAccountName -replace '[\\/:*?"<>|]', '_' $filePath = Join-Path $BackupPath "$safeFileName.json" $userBackup | ConvertTo-Json -Depth 10 | Out-File -FilePath $filePath -Encoding UTF8 Write-Host "[$counter/$totalUsers] $($user.SamAccountName) - $propertiesBackedUp properties" -ForegroundColor Cyan } $indexFile = @{ BackupDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" Server = $Server SearchBase = $SearchBase TotalUsers = $totalUsers AveragePropertiesPerUser = [math]::Round($totalPropertiesBackedUp / $totalUsers, 2) ExcludedProperties = $excludedProperties | Sort-Object Users = $users | Select-Object SamAccountName, UserPrincipalName, DisplayName, DistinguishedName, Enabled, @{N='ObjectGUID';E={$_.ObjectGUID.ToString()}} } $indexFile | ConvertTo-Json -Depth 5 | Out-File -FilePath (Join-Path $BackupPath "_index.json") -Encoding UTF8 Write-Progress -Activity "Backing up users" -Completed Write-Host "`n========================================" -ForegroundColor Green Write-Host "Backup completed" -ForegroundColor Green Write-Host "========================================" -ForegroundColor Green Write-Host "Location: $BackupPath" -ForegroundColor Yellow Write-Host "Users: $totalUsers" -ForegroundColor Yellow Write-Host "Properties: $totalPropertiesBackedUp" -ForegroundColor Yellow Write-Host "Average: $([math]::Round($totalPropertiesBackedUp / $totalUsers, 2)) per user" -ForegroundColor Yellow Write-Host "`nRestore examples:" -ForegroundColor Cyan Write-Host " Restore complete user (default):" -ForegroundColor Gray Write-Host " .\Restore-ADUser.ps1 -BackupPath `"$BackupPath`" -SamAccountName `"username`"" -ForegroundColor White Write-Host "`n Restore specific properties:" -ForegroundColor Gray Write-Host " .\Restore-ADUser.ps1 -BackupPath `"$BackupPath`" -SamAccountName `"username`" -Properties `"Title`",`"Department`"" -ForegroundColor White Write-Host "`n Preview changes (WhatIf):" -ForegroundColor Gray Write-Host " .\Restore-ADUser.ps1 -BackupPath `"$BackupPath`" -SamAccountName `"username`" -WhatIf -ShowDifferences" -ForegroundColor White Write-Host "========================================`n" -ForegroundColor Green

Restore-ADUser.ps1

Doel

Restore AD user properties vanuit een backup. Ondersteunt:

  • βœ… Complete restore (alle properties)

  • βœ… Selective restore (specifieke properties)

  • βœ… WhatIf mode (preview changes)

  • βœ… Diff view (show changes)

Parameters

Parameter

Type

Verplicht

Beschrijving

BackupPath

String

Ja

Pad naar backup folder

SamAccountName

String

Nee*

Username (SAM account)

UserPrincipalName

String

Nee*

UPN (email format)

Properties

String[]

Nee

Specifieke properties; leeg = alle

WhatIf

Switch

Nee

Preview mode (geen wijzigingen)

ShowDifferences

Switch

Nee

Toon verschillen

Server

String

Nee

Domain Controller

* Een van beide (SamAccountName of UserPrincipalName) is verplicht

Gebruik

1. Complete Restore

.\Restore-ADUser.ps1 ` -BackupPath "C:\AD_Backup\20250101_143052" ` -SamAccountName "john.doe"

Output:

======================================== Restoring: john.doe Backup: 2025-01-01 14:30:52 ======================================== βœ“ Title βœ“ Department βœ“ Manager βœ“ OfficePhone βœ“ MobilePhone ======================================== Complete: 5 restored ========================================

2. Selective Restore (Specific Properties)

.\Restore-ADUser.ps1 ` -BackupPath "C:\AD_Backup\20250101_143052" ` -SamAccountName "john.doe" ` -Properties "Title","Department","Manager"

Output:

======================================== Restoring: john.doe Backup: 2025-01-01 14:30:52 ======================================== βœ“ Title βœ“ Department βœ“ Manager ======================================== Complete: 3 restored ========================================

3. Preview Changes (WhatIf)

.\Restore-ADUser.ps1 ` -BackupPath "C:\AD_Backup\20250101_143052" ` -SamAccountName "john.doe" ` -WhatIf ` -ShowDifferences

Output:

======================================== Restoring: john.doe Backup: 2025-01-01 14:30:52 Mode: PREVIEW ONLY ======================================== Changes: Title Current: Developer Backup: Senior Developer Department Current: IT Backup: Engineering Manager Current: CN=Old Manager,OU=Managers,DC=company,DC=nl Backup: CN=New Manager,OU=Managers,DC=company,DC=nl Would restore 3 properties (preview mode)

4. Restore by UserPrincipalName

.\Restore-ADUser.ps1 ` -BackupPath "C:\AD_Backup\20250101_143052" ` -UserPrincipalName "john.doe@company.nl"

Het script zoekt automatisch de SamAccountName op in de index.

Error Handling

User niet gevonden in backup:

Error: Backup file not found for john.doe Path: C:\AD_Backup\20250101_143052\john.doe.json Similar files: john.smith jane.doe

User niet gevonden in AD:

Error: User not found in AD

Read-only property:

Skipped: ObjectGUID (Read-only)

Restore failure:

βœ“ Title βœ“ Department βœ— InvalidProperty: The property 'InvalidProperty' cannot be found βœ“ Manager ======================================== Complete: 3 restored Failed: 1 ========================================

Skipped Properties

Properties die niet gerestored kunnen worden:

  • Read-only system properties (ObjectGUID, SID, etc.)

  • Timestamps (WhenCreated, WhenChanged, etc.)

  • Logon statistics (lastLogon, badPwdCount, etc.)

Het script skip deze automatisch.

Script Code

# Restore-ADUser.ps1 <# .SYNOPSIS Restores AD user from backup .DESCRIPTION By default restores the complete user. Use -Properties to restore specific properties only. Can identify users by SamAccountName or UserPrincipalName. .EXAMPLE .\Restore-ADUser.ps1 -BackupPath "C:\AD_Backup\20250101_120000" -SamAccountName "jdoe" .EXAMPLE .\Restore-ADUser.ps1 -BackupPath "C:\AD_Backup\20250101_120000" -UserPrincipalName "jdoe@domain.com" .EXAMPLE .\Restore-ADUser.ps1 -BackupPath "C:\AD_Backup\20250101_120000" -SamAccountName "jdoe" -Properties "Title","Department" #> param( [Parameter(Mandatory=$true)] [string]$BackupPath, [Parameter(Mandatory=$false, ParameterSetName='BySamAccountName')] [string]$SamAccountName, [Parameter(Mandatory=$false, ParameterSetName='ByUserPrincipalName')] [string]$UserPrincipalName, [Parameter(Mandatory=$false)] [string[]]$Properties = @(), [Parameter(Mandatory=$false)] [switch]$WhatIf, [Parameter(Mandatory=$false)] [switch]$ShowDifferences, [Parameter(Mandatory=$false)] [string]$Server = $env:LOGONSERVER.Replace("\\", "") ) if (!$SamAccountName -and !$UserPrincipalName) { Write-Host "Error: Specify either -SamAccountName or -UserPrincipalName" -ForegroundColor Red return } Import-Module ActiveDirectory if ($UserPrincipalName) { $indexFile = Join-Path $BackupPath "_index.json" if (!(Test-Path $indexFile)) { Write-Host "Error: Index file not found" -ForegroundColor Red return } $index = Get-Content $indexFile -Raw | ConvertFrom-Json $userInfo = $index.Users | Where-Object { $_.UserPrincipalName -eq $UserPrincipalName } if (!$userInfo) { Write-Host "Error: User with UPN '$UserPrincipalName' not found in backup" -ForegroundColor Red return } $SamAccountName = $userInfo.SamAccountName } $safeFileName = $SamAccountName -replace '[\\/:*?"<>|]', '_' $backupFile = Join-Path $BackupPath "$safeFileName.json" if (!(Test-Path $backupFile)) { Write-Host "Error: Backup file not found for $SamAccountName" -ForegroundColor Red Write-Host "Path: $backupFile" -ForegroundColor Yellow $similarFiles = Get-ChildItem $BackupPath -Filter "*$SamAccountName*.json" -ErrorAction SilentlyContinue if ($similarFiles) { Write-Host "`nSimilar files:" -ForegroundColor Cyan $similarFiles | ForEach-Object { Write-Host " $($_.BaseName)" -ForegroundColor Gray } } return } $backup = Get-Content $backupFile -Raw | ConvertFrom-Json try { $currentUser = Get-ADUser -Identity $SamAccountName -Properties * -Server $Server } catch { Write-Host "Error: User not found in AD" -ForegroundColor Red return } if ($Properties.Count -eq 0) { $propertiesToRestore = $backup.Properties.PSObject.Properties.Name } else { $propertiesToRestore = $Properties } $readOnlyProperties = @( 'ObjectGUID', 'ObjectSID', 'SID', 'DistinguishedName', 'CN', 'WhenCreated', 'WhenChanged', 'Created', 'Modified', 'ObjectClass', 'ObjectCategory', 'DSCorePropagationData', 'InstanceType', 'lastLogon', 'lastLogonTimestamp', 'logonCount', 'badPwdCount', 'badPasswordTime', 'pwdLastSet', 'uSNCreated', 'uSNChanged', 'PropertyNames', 'PropertyCount', 'AddedProperties', 'ModifiedProperties', 'RemovedProperties' ) $restoreActions = @() $skippedProperties = @() $unchangedProperties = @() foreach ($propName in $propertiesToRestore) { if ($readOnlyProperties -contains $propName) { $skippedProperties += [PSCustomObject]@{ Property = $propName Reason = "Read-only" } continue } if ($null -eq $backup.Properties.$propName) { $skippedProperties += [PSCustomObject]@{ Property = $propName Reason = "Not in backup" } continue } $backupValue = $backup.Properties.$propName $currentValue = $currentUser.$propName $valuesEqual = $false if ($null -eq $backupValue -and $null -eq $currentValue) { $valuesEqual = $true } elseif ($null -ne $backupValue -and $null -ne $currentValue) { if ($backupValue -is [Array] -and $currentValue -is [Array]) { $valuesEqual = (@(Compare-Object $backupValue $currentValue).Count -eq 0) } elseif ($currentValue -is [DateTime]) { $backupDateTime = [DateTime]::Parse($backupValue) $valuesEqual = ($backupDateTime -eq $currentValue) } else { $valuesEqual = ($backupValue -eq $currentValue) } } if ($valuesEqual) { $unchangedProperties += $propName } else { $restoreActions += [PSCustomObject]@{ Property = $propName CurrentValue = $currentValue BackupValue = $backupValue } } } Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "Restoring: $SamAccountName" -ForegroundColor White Write-Host "Backup: $($backup.BackupDate)" -ForegroundColor Gray if ($WhatIf) { Write-Host "Mode: PREVIEW ONLY" -ForegroundColor Yellow } Write-Host "========================================" -ForegroundColor Cyan if ($ShowDifferences -and $restoreActions.Count -gt 0) { Write-Host "`nChanges:" -ForegroundColor Yellow foreach ($action in $restoreActions) { Write-Host " $($action.Property)" -ForegroundColor White Write-Host " Current: $($action.CurrentValue)" -ForegroundColor Red Write-Host " Backup: $($action.BackupValue)" -ForegroundColor Green } } if ($restoreActions.Count -eq 0) { Write-Host "`nNo changes needed" -ForegroundColor Green return } if ($WhatIf) { Write-Host "`nWould restore $($restoreActions.Count) properties (preview mode)" -ForegroundColor Yellow return } Write-Host "" $successCount = 0 $errorCount = 0 foreach ($action in $restoreActions) { try { $setParams = @{ Identity = $SamAccountName Server = $Server Replace = @{ $action.Property = $action.BackupValue } } Set-ADUser @setParams Write-Host "βœ“ $($action.Property)" -ForegroundColor Green $successCount++ } catch { Write-Host "βœ— $($action.Property): $($_.Exception.Message)" -ForegroundColor Red $errorCount++ } } Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "Complete: $successCount restored" -ForegroundColor Green if ($errorCount -gt 0) { Write-Host "Failed: $errorCount" -ForegroundColor Red } Write-Host "========================================`n" -ForegroundColor Cyan

Use Cases

Use Case 1: Voor IAM HR Sync Test

Je wilt IAM HR Sync testen zonder productie data te wijzigen.

Stap 1: Backup maken

.\Backup-ADUsers.ps1 -SearchBase "OU=Test Users,DC=company,DC=nl"

Stap 2: Run IAM HR Sync validation

Management Portal β†’ IAM HR Sync β†’ Run Validation

Stap 3: Check changes

Get-ADUser -Filter * -SearchBase "OU=Test Users,DC=company,DC=nl" -Properties Title, Department

Stap 4: Restore als je ontevreden bent

.\Restore-ADUser.ps1 ` -BackupPath "C:\AD_Backup\20250101_143052" ` -SamAccountName "test.user"

Use Case 2: Audit Trail

Je wilt bijhouden hoe employee data verandert over tijd.

Weekly backup:

# Schedule met Task Scheduler .\Backup-ADUsers.ps1 -BackupPath "D:\AD_Audit\Week_$(Get-Date -Format 'yyyy_ww')"

Compare backups:

# Week 1 $backup1 = Get-Content "D:\AD_Audit\Week_2025_01\_index.json" | ConvertFrom-Json # Week 2 $backup2 = Get-Content "D:\AD_Audit\Week_2025_02\_index.json" | ConvertFrom-Json # Compare Compare-Object $backup1.Users $backup2.Users -Property SamAccountName, DisplayName

Use Case 3: Disaster Recovery

AD corruption of accidental bulk change.

Recovery:

# Get latest backup $latestBackup = Get-ChildItem "C:\AD_Backup" | Sort-Object Name -Descending | Select-Object -First 1 # Restore alle users $users = (Get-Content "$($latestBackup.FullName)\_index.json" | ConvertFrom-Json).Users foreach ($user in $users) { .\Restore-ADUser.ps1 ` -BackupPath $latestBackup.FullName ` -SamAccountName $user.SamAccountName }

Use Case 4: Selective Property Restore

Je wilt alleen specifieke properties herstellen na een foutieve bulk update.

# Voorbeeld: Department was foutief geupdate voor hele OU # Get alle users in OU $users = Get-ADUser -Filter * -SearchBase "OU=Engineering,DC=company,DC=nl" # Restore alleen Department voor elke user foreach ($user in $users) { .\Restore-ADUser.ps1 ` -BackupPath "C:\AD_Backup\20250101_120000" ` -SamAccountName $user.SamAccountName ` -Properties "Department" }

Best Practices

1. Altijd Backup voor Bulk Changes

# βœ… GOED .\Backup-ADUsers.ps1 # Voer wijzigingen uit # Check resultaat # Restore indien nodig # ❌ FOUT # Direct bulk changes zonder backup

2. Gebruik WhatIf voor Preview

# Eerst preview .\Restore-ADUser.ps1 ... -WhatIf -ShowDifferences # Dan execute .\Restore-ADUser.ps1 ...

3. Reguliere Backups

# Weekly backup via Task Scheduler # Action: Start a program # Program: PowerShell.exe # Arguments: -File "C:\Scripts\Backup-ADUsers.ps1" -BackupPath "D:\AD_Backup\Auto\$(Get-Date -Format 'yyyyMMdd')"

4. Bewaar Backups

Retention policy: - Daily backups: 7 dagen - Weekly backups: 4 weken - Monthly backups: 12 maanden - Yearly backups: 5 jaar

5. Test Restores

# Periodiek testen of restores werken # Maak test user New-ADUser -Name "Test Restore User" -SamAccountName "test.restore" # Backup .\Backup-ADUsers.ps1 # Modify Set-ADUser "test.restore" -Title "Modified" # Restore .\Restore-ADUser.ps1 -BackupPath "..." -SamAccountName "test.restore" # Verify Get-ADUser "test.restore" -Properties Title

Troubleshooting

"ActiveDirectory module not found"

Probleem:

Error: ActiveDirectory module not found Install with: Install-WindowsFeature RSAT-AD-PowerShell

Oplossing:

# Windows Server Install-WindowsFeature RSAT-AD-PowerShell # Windows 10/11 Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0

"Access Denied"

Probleem: Scripts falen met access denied errors.

Oplossing:

  • Zorg dat je voldoende AD rechten hebt

  • Run PowerShell als Administrator

  • Controleer dat je lid bent van "Domain Admins" of vergelijkbare groep

"Backup file not found"

Probleem:

Error: Backup file not found for john.doe

Oplossing:

# Check index voor exacte username $index = Get-Content "C:\AD_Backup\20250101_143052\_index.json" | ConvertFrom-Json $index.Users | Where-Object { $_.DisplayName -like "*john*" }

Properties worden niet gerestored

Probleem: Sommige properties worden geskipt bij restore.

Oorzaken:

  1. Property is read-only → Kan niet gerestored worden

  2. Property bestaat niet in backup → Was excluded of null

  3. Waarde is identiek → Geen change nodig

Check:

# Run met WhatIf en ShowDifferences .\Restore-ADUser.ps1 ... -WhatIf -ShowDifferences

Zie Ook

Last modified: 23 March 2026