
Windows Infra Admin Skill
- 139 installs
- 404kidwiz/claude-supercode-skills
Manage Windows infrastructure, system administration, and deployment automation.
About
Windows infrastructure admin provides expertise in managing Windows-based infrastructure and systems. Use when administering Windows environments and automating Windows deployments.
- Windows admin
- System management
- Deployment automation
- Infrastructure
Windows Infra Admin by the numbers
- 139 all-time installs (skills.sh)
- Ranked #495 of 1,476 DevOps & CI/CD skills by installs in the Skillselion catalog
- Data as of Aug 11, 2026 (Skillselion catalog sync)
npx skills add https://github.com/404kidwiz/claude-supercode-skills --skill windows-infra-adminAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 139 |
|---|---|
| Repository | 404kidwiz/claude-supercode-skills ↗ |
What it does
Manage Windows infrastructure, system administration, and deployment automation.
Files
Windows Infrastructure Admin
Purpose
Provides Windows Server and enterprise administration expertise specializing in Active Directory, Hybrid Identity, and PowerShell automation. Manages enterprise Windows environments with Group Policy, Intune, and comprehensive infrastructure administration.
When to Use
- Designing or troubleshooting Active Directory topology (Forests, Domains, Sites)
- Implementing Group Policy Objects (GPO) for security hardening (CIS Benchmarks)
- Automating administrative tasks with PowerShell (User creation, Reporting)
- Configuring Hybrid Identity (Azure AD Connect / Cloud Sync)
- Managing Windows Server roles (DNS, DHCP, IIS, NPS, WSUS)
- Deploying endpoints via Intune / Autopilot
- Disaster Recovery planning for AD (Forest Recovery)
Examples
Example 1: AD Migration to Hybrid Identity
Scenario: Migrating on-premises AD to hybrid identity with Azure AD.
Implementation: 1. Designed Azure AD Connect sync topology 2. Implemented password hash synchronization 3. Configured seamless single sign-on 4. Set up conditional access policies 5. Created hybrid join certificates
Results:
- Seamless authentication for cloud apps
- 99% reduction in password-related support tickets
- Improved security posture with MFA
- Foundation for Microsoft 365 migration
Example 2: GPO Security Hardening
Scenario: Hardening Windows endpoints to CIS Benchmarks.
Implementation: 1. Analyzed current GPO landscape 2. Created security baseline GPO 3. Implemented password policies (NIST guidelines) 4. Configured firewall and BitLocker policies 5. Set up audit logging
Results:
- 95% compliance with CIS Benchmarks
- Security incidents reduced by 70%
- Passed external security audit
- Clear audit trail for compliance
Example 3: Intune Enrollment Automation
Scenario: Automating Windows device onboarding for remote workforce.
Implementation: 1. Configured Autopilot for zero-touch deployment 2. Created enrollment status screen policies 3. Imployed configuration profiles for security settings 4. Set up conditional access policies 5. Created self-service BitLocker recovery
Results:
- Devices ready for use within 30 minutes
- 80% reduction in IT support calls
- Consistent security configuration across devices
- Improved user satisfaction
Best Practices
Active Directory
- Health Monitoring: Regular dcdiag and repadmin checks
- Backup: Daily system state backups with tested restores
- Least Privilege: Separate admin from regular accounts
- Cleanup: Regular stale object removal
Group Policy
- Testing: Always test GPO in pilot first
- Documentation: Document GPO purpose and settings
- Security: Use security filtering appropriately
- Review: Annual GPO review and cleanup
PowerShell Automation
- Error Handling: Comprehensive try/catch/finally
- Modules: Create reusable modules
- Logging: Log all automation activities
- Testing: Test scripts before production use
Security
- Patching: Rapid patch deployment (within 30 days)
- MFA: Enforce MFA for all admin access
- Auditing: Enable advanced audit logging
- LAPS: Use for local administrator passwords
Hybrid Identity
- Sync Health: Monitor Azure AD Connect
- Conditional Access: Enforce policies for cloud access
- Password Protection: Enable banned password lists
- Access Reviews: Regular access reviews
Do NOT invoke when:
- Troubleshooting physical hardware failure → Use
network-engineer(if network) or vendor support - Managing Linux servers → Use
linux-admin(if available) ordevops-engineer - Developing .NET applications → Use
csharp-developer - Configuring cloud-native Azure resources (VMs, VNets) → Use
azure-infra-engineer
--- ---
Core Capabilities
Active Directory Management
- Managing AD forests, domains, and trusts
- Implementing user and group lifecycle management
- Configuring organizational units and delegation
- Troubleshooting authentication and replication issues
Group Policy Administration
- Creating and managing GPOs for security settings
- Implementing security baselines and CIS benchmarks
- Troubleshooting policy application issues
- Managing policy preferences and filtering
PowerShell Automation
- Writing PowerShell scripts for administration
- Automating user provisioning and reporting
- Managing Active Directory with modules
- Implementing error handling and logging
Hybrid Identity
- Configuring Entra ID Connect for synchronization
- Managing hybrid identity scenarios
- Implementing conditional access policies
- Managing device enrollment with Intune
--- ---
Workflow 2: Hybrid Identity Setup (Entra ID Connect)
Goal: Sync on-prem users to Azure AD for Office 365 access.
Steps:
1. Prerequisites
- Clean up AD (IdFix tool).
- Verified domain in Azure portal.
2. Install Azure AD Connect
- Select Password Hash Sync (PHS) (Most robust).
- Enable SSO (Single Sign-On).
3. Filtering
- Filter by OU (Sync only
User_OU, excludeAdmin_OUandService_Accounts).
4. Verification
- Check Synchronization Service Manager.
- Verify user appears in Azure Portal as "Directory Synced: Yes".
--- ---
4. Patterns & Templates
Pattern 1: Tiered Administration (Security)
Use case: Preventing credential theft (Pass-the-Hash).
- Tier 0 (Identity): Domain Admins. Can only log into DCs. (Red Card/Token).
- Tier 1 (Servers): Server Admins. Can log into Application Servers.
- Tier 2 (Workstations): Helpdesk. Can log into Workstations.
- Rule: Lower tiers CANNOT log into higher tier assets.
Pattern 2: DFS Namespaces (File Sharing)
Use case: Abstracting file server names.
- Bad: Mapping
\\Server01\Share. If Server01 dies, links break. - Good: Mapping
\\corp.com\Data\Share. -
\\corp.com\Datais the DFS Namespace. - It points to
\\Server01\Share(Target). - Migration to
\\Server02is invisible to users.
Pattern 3: JEA (Just Enough Administration)
Use case: Allowing Helpdesk to reset passwords without being Domain Admins.
# Role Capability File (.psrc)
VisibleCmdlets = @{
'Set-ADAccountPassword' = @{ Parameters = @{ Name = 'Identity' } }
'Unlock-ADAccount' = @{ Parameters = @{ Name = 'Identity' } }
}--- ---
6. Integration Patterns
azure-infra-engineer:
- Handoff: Windows Admin manages on-prem AD → Azure Engineer sets up Entra ID Connect.
- Collaboration: Extending AD to Azure via VPN (IaaS DCs).
- Tools: Azure Active Directory.
security-auditor:
- Handoff: Auditor requests "User Access Review" → Windows Admin runs PowerShell report on Group Membership.
- Collaboration: Enforcing Password Policies and MFA.
- Tools: AD Audit Plus, Splunk.
network-engineer:
- Handoff: Network Engineer sets up VLANs → Windows Admin configures DHCP Scopes/IP Helpers.
- Collaboration: DNS resolution (Split-brain DNS).
- Tools: IPAM.
---
Windows Infrastructure Admin - Quick Start Guide
This guide helps you get started with the Windows infrastructure admin skill's scripts and tools.
Prerequisites
- Windows Server 2016 or later
- Remote Server Administration Tools (RSAT) installed
- Domain Administrator privileges for most operations
- PowerShell 5.1 or later
- Active Directory module for AD operations
Installing Required Modules
# Install RSAT features (if not already installed)
Install-WindowsFeature RSAT-AD-PowerShell
Install-WindowsFeature RSAT-DNS-Server
Install-WindowsFeature RSAT-Group-Policy-Management
# Import modules
Import-Module ActiveDirectory
Import-Module DnsServer
Import-Module GroupPolicyAuthentication
The scripts require appropriate permissions:
- Active Directory Operations: Domain Admin or delegated permissions
- DNS Management: DNS Administrator or Domain Admin
- Group Policy: Group Policy Creator Owner or Domain Admin
Quick Examples
Managing Active Directory Users
# Create a new user
.\manage_ad_users.ps1 -Action Create `
-Username "jdoe" `
-FirstName "John" `
-LastName "Doe" `
-Email "jdoe@example.com" `
-OU "OU=Users,DC=example,DC=com" `
-Enabled $true
# List all users
.\manage_ad_users.ps1 -Action List
# Disable a user account
.\manage_ad_users.ps1 -Action Disable -Username "jdoe"
# Enable a user account
.\manage_ad_users.ps1 -Action Enable -Username "jdoe"
# Update user information
.\manage_ad_users.ps1 -Action Update `
-Username "jdoe" `
-Email "john.doe@newdomain.com" `
-FirstName "Jonathan"Configuring DNS
# Create a new DNS zone
.\configure_dns.ps1 -Action CreateZone -ZoneName "example.com"
# Create an A record
.\configure_dns.ps1 -Action CreateRecord `
-ZoneName "example.com" `
-RecordName "www" `
-RecordType "A" `
-RecordData "192.168.1.10"
# Create an MX record
.\configure_dns.ps1 -Action CreateRecord `
-ZoneName "example.com" `
-RecordName "@" `
-RecordType "MX" `
-RecordData "mail.example.com" `
-Priority 10
# Query DNS
.\configure_dns.ps1 -Action QueryDNS -ZoneName "www.example.com" -RecordType "A"
# Test DNS health
.\configure_dns.ps1 -Action TestDNS -ZoneName "example.com"Managing Group Policy
# Create a new GPO
.\setup_gpo.ps1 -Action CreateGPO `
-GPOName "Workstation Security" `
-Description "Security policies for workstations"
# Link GPO to OU
.\setup_gpo.ps1 -Action LinkGPO `
-GPOName "Workstation Security" `
-TargetOU "OU=Workstations,DC=example,DC=com"
# List all GPOs
.\setup_gpo.ps1 -Action ListGPOs
# Backup a GPO
.\setup_gpo.ps1 -Action BackupGPO `
-GPOName "Workstation Security" `
-BackupPath ".\GPOBackups"
# Generate GPO report
.\setup_gpo.ps1 -Action ReportGPO -GPOName "Workstation Security"Common Patterns
Batch User Creation
$users = @(
@{Username="user1"; FirstName="User"; LastName="One"; Email="user1@example.com"},
@{Username="user2"; FirstName="User"; LastName="Two"; Email="user2@example.com"}
)
foreach ($user in $users) {
.\manage_ad_users.ps1 -Action Create `
-Username $user.Username `
-FirstName $user.FirstName `
-LastName $user.LastName `
-Email $user.Email
}Bulk DNS Record Creation
$records = @(
@{Name="www"; Type="A"; Data="192.168.1.10"},
@{Name="mail"; Type="A"; Data="192.168.1.20"},
@{Name="ftp"; Type="A"; Data="192.168.1.30"}
)
foreach ($record in $records) {
.\configure_dns.ps1 -Action CreateRecord `
-ZoneName "example.com" `
-RecordName $record.Name `
-RecordType $record.Type `
-RecordData $record.Data
}GPO Security Settings
$settings = @{
PasswordPolicy = @{
MinLength = 12
History = 12
MaxAgeDays = 60
}
AuditPolicy = @{
"Logon" = @{Success = $true; Failure = $true}
"Privilege Use" = @{Success = $true; Failure = $true}
"Process Tracking" = @{Success = $false; Failure = $false}
}
}
.\setup_gpo.ps1 -Action ApplySettings `
-GPOName "Security Baseline" `
-GPOSettings $settingsBest Practices
1. Test in lab environment first - Always test scripts in a non-production environment 2. Use descriptive OU structures - Organize OUs by function, location, or department 3. Document GPO changes - Keep a record of GPO modifications and their purposes 4. Backup before changes - Always backup GPOs before making modifications 5. Use least privilege - Grant only necessary permissions for scripts 6. Enable logging - Use the LogPath parameter to track operations 7. Validate inputs - All scripts include built-in validation 8. Plan DNS changes - Document DNS record changes and maintain a DNS inventory
Troubleshooting
AD Module Not Found
Error: Active Directory module not availableSolution:
Install-WindowsFeature RSAT-AD-PowerShell -IncludeManagementTools
Import-Module ActiveDirectoryPermission Denied Errors
Error: Access deniedSolutions: 1. Run PowerShell as Administrator 2. Ensure you have Domain Admin privileges 3. Check if the account has necessary delegated permissions
GPO Link Failed
Error: Failed to link GPOSolutions: 1. Verify the OU path is correct 2. Ensure the GPO exists 3. Check if you have permissions on the target OU
DNS Record Not Resolving
Error: DNS query failedSolutions: 1. Check if the DNS server service is running 2. Verify the record exists 3. Check DNS server replication 4. Test with nslookup command
User Creation Fails
Error: Failed to create userSolutions: 1. Check if username already exists 2. Verify OU path is valid 3. Ensure password policy allows the temporary password 4. Check if account has Create User permissions in the OU
Useful PowerShell Commands
# Find a user
Get-ADUser -Filter {Name -like "*John*"}
# Check user groups
Get-ADUser -Identity "jdoe" -Properties MemberOf | Select-Object -ExpandProperty MemberOf
# Get GPO links
Get-GPLink -Target "OU=Users,DC=example,DC=com"
# Test DNS resolution
Resolve-DnsName -Name "www.example.com"
# Check DNS server status
Get-Service -Name DNS
# Get DNS zones
Get-DnsServerZone
# View GPO inheritance
gpresult /rSecurity Considerations
1. Secure credentials - Never hardcode passwords in scripts 2. Use managed service accounts - For automated tasks 3. Audit privileged operations - Enable logging for admin actions 4. Implement tiered administration - Separate admin and regular user accounts 5. Regular password rotations - Use managed service accounts with automatic password rotation 6. Monitor AD changes - Set up alerts for critical AD modifications
Additional Resources
Windows Infrastructure Patterns
Common patterns and best practices for Windows infrastructure administration.
Active Directory Patterns
OU Structure Design
# Recommended OU hierarchy
$OUStructure = @(
"DC=example,DC=com",
"OU=Users,DC=example,DC=com",
"OU=Groups,DC=example,DC=com",
"OU=Computers,DC=example,DC=com",
"OU=Servers,DC=example,DC=com",
"OU=Workstations,DC=example,DC=com",
"OU=Resources,DC=example,DC=com",
"OU=SharedFolders,OU=Resources,DC=example,DC=com",
"OU=Printers,OU=Resources,DC=example,DC=com"
)
# Create OU structure
foreach ($OU in $OUStructure) {
$OUParts = $OU -split ',' | Where-Object { $_ -match '^OU=' }
$currentPath = $OU
$parentPath = ""
foreach ($part in $OUParts) {
$name = $part -replace '^OU=', ''
if ($parentPath) {
$currentPath = "OU=$name,$parentPath"
} else {
$currentPath = "OU=$name,DC=example,DC=com"
}
try {
New-ADOrganizationalUnit -Name $name -Path $parentPath -ErrorAction Stop
} catch {
Write-Warning "OU $name already exists"
}
$parentPath = $currentPath
}
}User Group Management Pattern
function Add-UserToGroupSmart {
param(
[string]$Username,
[string]$GroupName,
[string]$Domain = "example.com"
)
try {
$user = Get-ADUser -Identity $Username -ErrorAction Stop
$group = Get-ADGroup -Identity $GroupName -ErrorAction Stop
if ($user.DistinguishedName -in $group.Members) {
Write-Warning "User $Username is already a member of $GroupName"
return $false
}
Add-ADGroupMember -Identity $GroupName -Members $Username
Write-Host "Added $Username to $GroupName"
return $true
}
catch {
Write-Error "Failed to add user to group: $($_.Exception.Message)"
return $false
}
}
# Bulk add users to group
$users = Get-Content "users.txt"
foreach ($user in $users) {
Add-UserToGroupSmart -Username $user -GroupName "Department-IT"
}Computer Object Lifecycle
# New computer onboarding
$computerName = "DESKTOP-001"
$OU = "OU=Workstations,DC=example,DC=com"
New-ADComputer -Name $computerName -Path $OU -Enabled $true
# Join specific groups
Add-ADGroupMember -Identity "Workstation-Standard" -Members $computerName
Add-ADGroupMember -Identity "WSUS-Clients" -Members $computerName
# Set description
Set-ADComputer -Identity $computerName -Description "Assigned to: John Doe (Finance)"
# Computer offboarding
$computerName = "DESKTOP-001"
# Disable and move to disabled OU
Disable-ADAccount -Identity $computerName
$disabledOU = "OU=Disabled Computers,DC=example,DC=com"
Move-ADObject -Identity (Get-ADComputer $computerName).DistinguishedName -TargetPath $disabledOU
# Remove from sensitive groups
$groups = (Get-ADComputer $computerName -Properties MemberOf).MemberOf
foreach ($group in $groups) {
Remove-ADGroupMember -Identity $group -Members $computerName -Confirm:$false
}DNS Management Patterns
DNS Zone Standardization
# Standard DNS records for new domain
function Initialize-StandardDNSRecords {
param(
[string]$Domain,
[string]$WebServerIP,
[string]$MailServerIP,
[string]$DNSServer
)
# A records
@(
@{Name="@"; IP=$WebServerIP; Desc="Domain Root"},
@{Name="www"; IP=$WebServerIP; Desc="Web Server"},
@{Name="mail"; IP=$MailServerIP; Desc="Mail Server"},
@{Name="autodiscover"; IP=$MailServerIP; Desc="Exchange Autodiscover"}
) | ForEach-Object {
Add-DnsServerResourceRecordA -Name $_.Name -ZoneName $Domain `
-IPv4Address $_.IP -ComputerName $DNSServer -ErrorAction SilentlyContinue
Write-Host "Created A record: $($_.Name).$Domain -> $($_.IP)"
}
# MX record
Add-DnsServerResourceRecordMX -Name "@" -ZoneName $Domain `
-MailExchange "mail.$Domain" -Preference 10 -ComputerName $DNSServer
# SPF record
$spfRecord = "v=spf1 include:_spf.google.com ~all"
Add-DnsServerResourceRecordTxt -Name "@" -ZoneName $Domain `
-DescriptiveText $spfRecord -ComputerName $DNSServer
}DNS Failover Pattern
# Configure round-robin DNS for load balancing
function Set-DNSRoundRobin {
param(
[string]$Domain,
[string]$RecordName,
[string[]]$IPAddresses,
[string]$DNSServer
)
# Remove existing records
Get-DnsServerResourceRecord -Name $RecordName -ZoneName $Domain -ComputerName $DNSServer |
Remove-DnsServerResourceRecord -ZoneName $Domain -ComputerName $DNSServer -Force
# Add new records (one for each IP)
foreach ($IP in $IPAddresses) {
Add-DnsServerResourceRecordA -Name $RecordName -ZoneName $Domain `
-IPv4Address $IP -ComputerName $DNSServer
}
}
# Use multiple IPs for redundancy
Set-DNSRoundRobin -Domain "example.com" -RecordName "www" `
-IPAddresses @("192.168.1.10", "192.168.1.11", "192.168.1.12") `
-DNSServer "dc01.example.com"DNS Aging and Scavenging
# Enable DNS scavenging to remove stale records
$zone = "example.com"
$server = "dc01.example.com"
# Configure scavenging on zone
Set-DnsServerZoneAging -Name $zone -ComputerName $server `
-AgingEnabled $true `
-NoRefreshInterval 7.00:00:00 `
-RefreshInterval 7.00:00:00
# Enable scavenging on server
Set-DnsServerScavenging -ComputerName $server `
-ScavengingState $true `
-ScavengingInterval 7.00:00:00Group Policy Patterns
GPO Naming Convention
# Standard GPO naming: <Scope>-<Function>-<Environment>
$gpoTemplates = @(
"SEC-Password-Policy-Prod",
"SEC-Account-Lockout-Prod",
"CFG-Desktop-Background-Prod",
"CFG-Software-Deployment-Prod",
"APP-Office-Deployment-Prod",
"APP-Antivirus-Deployment-Prod"
)
foreach ($gpoName in $gpoTemplates) {
New-GPO -Name $gpoName
}GPO Inheritance Control
# Block inheritance at OU level
Set-GPInheritance -Target "OU=Computers,DC=example,DC=com" -IsBlocked Yes
# Enforce GPO at OU level (Block inheritance from above)
$gpo = Get-GPO -Name "Critical Security"
New-GPLink -Guid $gpo.Id -Target "OU=Servers,DC=example,DC=com" -Enforced Yes
# Remove block inheritance
Set-GPInheritance -Target "OU=Computers,DC=example,DC=com" -IsBlocked NoWMI Filters for Conditional GPO Application
# Create WMI filter for laptops
$wmiQuery = "SELECT * FROM Win32_ComputerSystem WHERE PCSystemType = 2"
$wmiFilterName = "Is Laptop"
$namespace = "root\cimv2"
$query = [Wmi]::CreateQuery("SELECT * FROM MSFT_SomFilter WHERE Name='$wmiFilterName'")
# Create filter
$wmiFilter = New-Object -TypeName Microsoft.GroupPolicy.WmiFilter
$wmiFilter.Name = $wmiFilterName
$wmiFilter.Namespace = $namespace
$wmiFilter.Query = $wmiQuery
$wmiFilter.Description = "Filter for laptop computers"
# Apply filter to GPO
$gpo = Get-GPO -Name "Laptop Security Policy"
Set-GPRegistryValue -Guid $gpo.Id -Key "HKLM\Software\Policies\Microsoft" `
-ValueName "WmiFilter" -Type String -Value $wmiFilter.NameGPO Security Baseline Pattern
function Apply-SecurityBaseline {
param(
[string]$GPOName,
[string]$TargetOU
)
$gpo = New-GPO -Name $GPOName -Comment "Security baseline configuration"
# Password policy
$gpoPath = $gpo.Path
$securitySettingsPath = "$gpoPath\Machine\Microsoft\Windows NT\SecEdit"
# Create secedit.inf
$infContent = @"
[Unicode]
Unicode=yes
[Version]
signature="`$CHICAGO`$"
Revision=1
[System Access]
MinimumPasswordLength = 12
PasswordComplexity = 1
PasswordHistorySize = 12
MaximumPasswordAge = 60
LockoutThreshold = 5
LockoutDuration = 15
LockoutObservationWindow = 15
"@
$infFile = "$env:TEMP\security.inf"
$infContent | Out-File -FilePath $infFile -Encoding Unicode
# Apply to GPO
secedit /configure /db secedit.sdb /cfg $infFile /areas SECURITYPOLICY
# Link GPO
New-GPLink -Guid $gpo.Id -Target $TargetOU -LinkEnabled Yes
# Clean up
Remove-Item $infFile -Force
}Security Patterns
Privileged Account Management
# Tier 0: Enterprise Admin, Domain Admin (rarely used, no internet access)
# Tier 1: Server Admins (manage servers)
# Tier 2: Helpdesk (manage user workstations)
function Create-AdminAccount {
param(
[string]$Username,
[ValidateSet('Tier0', 'Tier1', 'Tier2')]
[string]$AdminTier,
[string]$FirstName,
[string]$LastName
)
$OU = switch ($AdminTier) {
'Tier0' { "OU=Tier0 Admins,OU=Admins,DC=example,DC=com" }
'Tier1' { "OU=Tier1 Admins,OU=Admins,DC=example,DC=com" }
'Tier2' { "OU=Tier2 Admins,OU=Admins,DC=example,DC=com" }
}
# Create admin account
New-ADUser -SamAccountName $Username -GivenName $FirstName -Surname $LastName `
-Name "$FirstName $LastName" -Path $OU -Enabled $false `
-ChangePasswordAtLogon $true
# Add to appropriate admin group
$adminGroup = switch ($AdminTier) {
'Tier0' { "Enterprise Admins" }
'Tier1' { "Server Admins" }
'Tier2' { "Helpdesk Admins" }
}
Add-ADGroupMember -Identity $adminGroup -Members $Username
}Account Lockout Monitoring
# Monitor for account lockouts
function Get-AccountLockouts {
param(
[int]$Hours = 24
)
$startTime = (Get-Date).AddHours(-$Hours)
Get-WinEvent -LogName Security -FilterXPath "*[System[EventID=4740]]" |
Where-Object { $_.TimeCreated -gt $startTime } |
ForEach-Object {
$data = $_.Properties[0].Value
$computer = $_.Properties[1].Value
[PSCustomObject]@{
Timestamp = $_.TimeCreated
Account = $data
LockedOnComputer = $computer
}
} | Format-Table -AutoSize
}Password Expiration Notifications
function Send-PasswordExpirationAlerts {
param(
[int]$DaysWarning = 14
)
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.Days
$warningDate = (Get-Date).AddDays($DaysWarning)
Get-ADUser -Filter {Enabled -eq $true -and PasswordNeverExpires -eq $false} -Properties PasswordLastSet |
Where-Object { $_.PasswordLastSet -and $_.PasswordLastSet.AddDays($maxPasswordAge) -le $warningDate } |
ForEach-Object {
$daysUntilExpire = ($_.PasswordLastSet.AddDays($maxPasswordAge) - (Get-Date)).Days
Send-MailMessage -To "$($_.GivenName) <$($_.EmailAddress)>" `
-From "IT Support <it@example.com>" `
-Subject "Password expiring in $daysUntilExpire days" `
-Body "Your password will expire in $daysUntilExpire days. Please change it soon." `
-SmtpServer "smtp.example.com"
}
}Backup and Recovery Patterns
Automated AD Backup
function Backup-ActiveDirectory {
param(
[string]$BackupPath = "\\backup\ADBackups"
)
$date = Get-Date -Format "yyyy-MM-dd"
$backupFile = "$BackupPath\AD-$date.bak"
# Use Windows Server Backup
wbadmin start backup -backupTarget:$backupFile -include:"C:\Windows\NTDS" `
-include:"C:\Windows\SYSVOL" -systemState -allCritical -quiet
# Backup GPOs
$gpoBackupPath = "$BackupPath\GPOs-$date"
Get-GPO -All | ForEach-Object {
Backup-GPO -Guid $_.Id -Path $gpoBackupPath
}
# Backup DNS zones
$dnsBackupPath = "$BackupPath\DNS-$date"
Get-DnsServerZone | ForEach-Object {
Export-DnsServerZone -Name $_.ZoneName -FileName "$dnsBackupPath\$($_.ZoneName).dns"
}
Write-Host "Backup completed to $BackupPath"
}GPO Restoration
function Restore-GPOFromBackup {
param(
[string]$BackupID,
[string]$BackupPath,
[switch]$OverwriteExisting
)
if ($OverwriteExisting) {
Restore-GPO -BackupId $BackupID -Path $BackupPath
}
else {
$backup = Get-GPOBackup -Path $BackupPath -Guid $BackupID
$existingGPO = Get-GPO -Name $backup.DisplayName -ErrorAction SilentlyContinue
if ($existingGPO) {
Write-Warning "GPO $($backup.DisplayName) already exists"
return
}
Restore-GPO -BackupId $BackupID -Path $BackupPath
}
}Monitoring Patterns
Event Log Monitoring
function Get-SecurityEvents {
param(
[int]$EventID,
[int]$Hours = 24,
[string]$ComputerName = $env:COMPUTERNAME
)
$startTime = (Get-Date).AddHours(-$Hours)
Get-WinEvent -ComputerName $ComputerName -LogName Security `
-FilterXPath "*[System[EventID=$EventID]]" |
Where-Object { $_.TimeCreated -gt $startTime } |
Select-Object TimeCreated, Message | Format-Table -AutoSize
}
# Monitor failed logons
Get-SecurityEvents -EventID 4625 -Hours 24
# Monitor privileged group changes
Get-SecurityEvents -EventID 4728 -Hours 24System Health Check
function Test-SystemHealth {
param([string]$ComputerName = $env:COMPUTERNAME)
$results = [PSCustomObject]@{}
$results.AD = Test-ComputerSecureChannel -Server $env:USERDNSDOMAIN -ErrorAction SilentlyContinue
$results.DNS = Resolve-DnsName $env:COMPUTERNAME -ErrorAction SilentlyContinue
$results.Time = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ComputerName | Select-Object LocalDateTime
$criticalServices = @("NetLogon", "DNS", "W32Time")
foreach ($service in $criticalServices) {
$serviceStatus = Get-Service -Name $service -ComputerName $ComputerName -ErrorAction SilentlyContinue
$results | Add-Member -MemberType NoteProperty -Name $service -Value $serviceStatus.Status
}
return $results
}# DNS Configuration and Management Script
<#
.SYNOPSIS
Configures and manages DNS zones and records
.DESCRIPTION
This script provides comprehensive DNS management functionality including
zone creation, record management, and DNS health checks.
.PARAMETER Action
The action to perform (CreateZone, CreateRecord, DeleteRecord, QueryDNS, TestDNS)
.PARAMETER ZoneName
The DNS zone name
.PARAMETER RecordName
The DNS record name
.PARAMETER RecordType
The DNS record type (A, AAAA, CNAME, MX, NS, TXT, SRV)
.PARAMETER RecordData
The data for the DNS record
.PARAMETER DNSServer
The DNS server to manage (default: local)
.EXAMPLE
.\configure_dns.ps1 -Action CreateZone -ZoneName "example.com"
.EXAMPLE
.\configure_dns.ps1 -Action CreateRecord -ZoneName "example.com" -RecordName "www" -RecordType "A" -RecordData "192.168.1.10"
#>
param(
[Parameter(Mandatory=$true)]
[ValidateSet('CreateZone', 'CreateRecord', 'DeleteRecord', 'QueryDNS', 'TestDNS', 'ListZones')]
[string]$Action,
[Parameter(Mandatory=$false)]
[string]$ZoneName,
[Parameter(Mandatory=$false)]
[string]$RecordName,
[Parameter(Mandatory=$false)]
[ValidateSet('A', 'AAAA', 'CNAME', 'MX', 'NS', 'TXT', 'SRV', 'PTR')]
[string]$RecordType,
[Parameter(Mandatory=$false)]
[string]$RecordData,
[Parameter(Mandatory=$false)]
[int]$Priority,
[Parameter(Mandatory=$false)]
[string]$DNSServer = $env:COMPUTERNAME,
[Parameter(Mandatory=$false)]
[string]$LogPath = ".\dns_management.log"
)
$ErrorActionPreference = "Stop"
function Write-Log {
param(
[string]$Message,
[ValidateSet('INFO', 'WARNING', 'ERROR')]
[string]$Level = 'INFO'
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "[$timestamp] [$Level] $Message"
Write-Host $logEntry
Add-Content -Path $LogPath -Value $logEntry
}
function Test-DNSServerAvailable {
param([string]$Server)
try {
Test-Connection -ComputerName $Server -Count 1 -Quiet
}
catch {
Write-Log "DNS server $Server is not reachable" -Level 'ERROR'
return $false
}
}
function Test-IPAddress {
param([string]$IPAddress)
return $IPAddress -match '^(?:(?: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]?)$'
}
function New-DNSZoneAdvanced {
param(
[string]$ZoneName,
[string]$DNSServer
)
Write-Log "Creating DNS zone: $ZoneName" -Level 'INFO'
if (-not (Test-DNSServerAvailable -Server $DNSServer)) {
return @{
Success = $false
Error = "DNS server not reachable"
}
}
try {
Add-DnsServerPrimaryZone -Name $ZoneName -ComputerName $DNSServer -ReplicationScope Forest
Write-Log "DNS zone $ZoneName created successfully" -Level 'INFO'
return @{
Success = $true
ZoneName = $ZoneName
}
}
catch {
if ($_.Exception.Message -match 'zone already exists') {
Write-Log "DNS zone $ZoneName already exists" -Level 'WARNING'
return @{
Success = $false
Error = "Zone already exists"
}
}
Write-Log "Failed to create DNS zone $ZoneName`: $($_.Exception.Message)" -Level 'ERROR'
return @{
Success = $false
Error = $_.Exception.Message
}
}
}
function New-DNSRecordAdvanced {
param(
[string]$ZoneName,
[string]$RecordName,
[string]$RecordType,
[string]$RecordData,
[int]$Priority,
[string]$DNSServer
)
Write-Log "Creating DNS record: $RecordName.$ZoneName ($RecordType)" -Level 'INFO'
if (-not (Test-DNSServerAvailable -Server $DNSServer)) {
return @{
Success = $false
Error = "DNS server not reachable"
}
}
try {
$fullRecordName = if ($RecordName -eq $ZoneName -or $RecordName -eq '@') {
$ZoneName
}
else {
"$RecordName.$ZoneName"
}
switch ($RecordType) {
'A' {
if (-not (Test-IPAddress -IPAddress $RecordData)) {
throw "Invalid IP address format: $RecordData"
}
Add-DnsServerResourceRecordA -Name $RecordName -ZoneName $ZoneName -IPv4Address $RecordData -ComputerName $DNSServer
}
'AAAA' {
Add-DnsServerResourceRecordAAAA -Name $RecordName -ZoneName $ZoneName -IPv6Address $RecordData -ComputerName $DNSServer
}
'CNAME' {
Add-DnsServerResourceRecordCName -Name $RecordName -ZoneName $ZoneName -HostNameAlias $RecordData -ComputerName $DNSServer
}
'MX' {
if (-not $Priority) {
throw "Priority is required for MX records"
}
Add-DnsServerResourceRecordMX -Name $RecordName -ZoneName $ZoneName -MailExchange $RecordData -Preference $Priority -ComputerName $DNSServer
}
'TXT' {
Add-DnsServerResourceRecordTxt -Name $RecordName -ZoneName $ZoneName -DescriptiveText $RecordData -ComputerName $DNSServer
}
'SRV' {
$service, $proto, $port = $RecordName -split '\.'
Add-DnsServerResourceRecordSRV -Name "$service.$proto" -ZoneName $ZoneName -DomainName $RecordData -Port $port -Priority $Priority -ComputerName $DNSServer
}
default {
throw "Unsupported record type: $RecordType"
}
}
Write-Log "DNS record $fullRecordName created successfully" -Level 'INFO'
return @{
Success = $true
RecordName = $fullRecordName
RecordType = $RecordType
RecordData = $RecordData
}
}
catch {
Write-Log "Failed to create DNS record $RecordName.$ZoneName`: $($_.Exception.Message)" -Level 'ERROR'
return @{
Success = $false
Error = $_.Exception.Message
}
}
}
function Remove-DNSRecordAdvanced {
param(
[string]$ZoneName,
[string]$RecordName,
[string]$RecordType,
[string]$DNSServer
)
Write-Log "Deleting DNS record: $RecordName.$ZoneName ($RecordType)" -Level 'INFO'
try {
$record = Get-DnsServerResourceRecord -ZoneName $ZoneName -Name $RecordName -ComputerName $DNSServer -ErrorAction Stop
Remove-DnsServerResourceRecord -ZoneName $ZoneName -Name $RecordName -ComputerName $DNSServer -Force
Write-Log "DNS record $RecordName.$ZoneName deleted successfully" -Level 'INFO'
return @{
Success = $true
RecordName = "$RecordName.$ZoneName"
}
}
catch {
Write-Log "Failed to delete DNS record $RecordName.$ZoneName`: $($_.Exception.Message)" -Level 'ERROR'
return @{
Success = $false
Error = $_.Exception.Message
}
}
}
function Get-DNSQuery {
param(
[string]$Name,
[string]$Type = 'A',
[string]$DNSServer = '8.8.8.8'
)
Write-Log "Querying DNS: $Name ($Type)" -Level 'INFO'
try {
$result = Resolve-DnsName -Name $Name -Type $Type -Server $DNSServer -ErrorAction Stop
$records = $result | Where-Object { $_.Type -eq $Type } | ForEach-Object {
[PSCustomObject]@{
Name = $_.Name
Type = $_.Type
TTL = $_.TTL
Data = $_.IPAddress ?? $_.NameHost ?? $_.StringsJoined
}
}
return @{
Success = $true
Records = $records
}
}
catch {
Write-Log "DNS query failed for $Name`: $($_.Exception.Message)" -Level 'ERROR'
return @{
Success = $false
Error = $_.Exception.Message
}
}
}
function Test-DNSHealth {
param(
[string]$Domain,
[string]$DNSServer
)
Write-Log "Testing DNS health for: $Domain" -Level 'INFO'
$tests = @()
$tests += @{
Test = "Resolve A Record"
Success = (Resolve-DnsName -Name $Domain -Type A -Server $DNSServer -ErrorAction SilentlyContinue) -ne $null
}
$tests += @{
Test = "Resolve NS Records"
Success = (Resolve-DnsName -Name $Domain -Type NS -Server $DNSServer -ErrorAction SilentlyContinue) -ne $null
}
$tests += @{
Test = "Resolve MX Records"
Success = (Resolve-DnsName -Name $Domain -Type MX -Server $DNSServer -ErrorAction SilentlyContinue) -ne $null
}
$tests += @{
Test = "DNS Server Response Time"
Success = (Measure-Command { Resolve-DnsName -Name $Domain -Type A -Server $DNSServer }).TotalMilliseconds -lt 1000
}
$passedTests = ($tests | Where-Object { $_.Success }).Count
$totalTests = $tests.Count
Write-Log "DNS health test completed: $passedTests/$totalTests passed" -Level 'INFO'
return @{
Success = $true
Tests = $tests
Passed = $passedTests
Total = $totalTests
}
}
function Get-DNSZoneList {
param([string]$DNSServer)
Write-Log "Listing DNS zones on: $DNSServer" -Level 'INFO'
try {
$zones = Get-DnsServerZone -ComputerName $DNSServer
$zoneList = $zones | ForEach-Object {
[PSCustomObject]@{
ZoneName = $_.ZoneName
ZoneType = $_.ZoneType
IsReverseLookupZone = $_.IsReverseLookupZone
IsDsIntegrated = $_.IsDsIntegrated
IsAutoCreated = $_.IsAutoCreated
}
}
return @{
Success = $true
Zones = $zoneList
}
}
catch {
Write-Log "Failed to list DNS zones`: $($_.Exception.Message)" -Level 'ERROR'
return @{
Success = $false
Error = $_.Exception.Message
}
}
}
switch ($Action) {
'CreateZone' {
if (-not $ZoneName) {
Write-Log "ZoneName is required for CreateZone action" -Level 'ERROR'
exit 1
}
$result = New-DNSZoneAdvanced -ZoneName $ZoneName -DNSServer $DNSServer
}
'CreateRecord' {
if (-not $ZoneName -or -not $RecordName -or -not $RecordType -or -not $RecordData) {
Write-Log "ZoneName, RecordName, RecordType, and RecordData are required for CreateRecord action" -Level 'ERROR'
exit 1
}
$result = New-DNSRecordAdvanced -ZoneName $ZoneName -RecordName $RecordName -RecordType $RecordType -RecordData $RecordData -Priority $Priority -DNSServer $DNSServer
}
'DeleteRecord' {
if (-not $ZoneName -or -not $RecordName -or -not $RecordType) {
Write-Log "ZoneName, RecordName, and RecordType are required for DeleteRecord action" -Level 'ERROR'
exit 1
}
$result = Remove-DNSRecordAdvanced -ZoneName $ZoneName -RecordName $RecordName -RecordType $RecordType -DNSServer $DNSServer
}
'QueryDNS' {
if (-not $ZoneName) {
Write-Log "ZoneName is required for QueryDNS action" -Level 'ERROR'
exit 1
}
$result = Get-DNSQuery -Name $ZoneName -Type $RecordType
}
'TestDNS' {
if (-not $ZoneName) {
Write-Log "ZoneName is required for TestDNS action" -Level 'ERROR'
exit 1
}
$result = Test-DNSHealth -Domain $ZoneName -DNSServer $DNSServer
}
'ListZones' {
$result = Get-DNSZoneList -DNSServer $DNSServer
}
}
if ($result.Success) {
Write-Log "Operation completed successfully" -Level 'INFO'
if ($result.Records) {
$result.Records | Format-Table -AutoSize
}
elseif ($result.Zones) {
$result.Zones | Format-Table -AutoSize
}
elseif ($result.Tests) {
$result.Tests | Format-Table -AutoSize
}
}
else {
Write-Log "Operation failed: $($result.Error)" -Level 'ERROR'
exit 1
}
# Active Directory User Management Script
<#
.SYNOPSIS
Manages Active Directory users with comprehensive functionality
.DESCRIPTION
This script provides functions for creating, updating, and managing Active Directory users
with proper validation, error handling, and logging.
.PARAMETER Username
The username for the AD user
.PARAMETER FirstName
First name of the user
.PARAMETER LastName
Last name of the user
.PARAMETER Email
Email address of the user
.PARAMETER OU
Organizational Unit path for the user
.PARAMETER Enabled
Enable or disable the user account
.EXAMPLE
.\manage_ad_users.ps1 -Action Create -Username "jdoe" -FirstName "John" -LastName "Doe" -Email "jdoe@example.com" -OU "OU=Users,DC=example,DC=com"
#>
param(
[Parameter(Mandatory=$true)]
[ValidateSet('Create', 'Update', 'Delete', 'Disable', 'Enable', 'List')]
[string]$Action,
[Parameter(Mandatory=$false)]
[string]$Username,
[Parameter(Mandatory=$false)]
[string]$FirstName,
[Parameter(Mandatory=$false)]
[string]$LastName,
[Parameter(Mandatory=$false)]
[string]$Email,
[Parameter(Mandatory=$false)]
[string]$OU = "OU=Users,DC=example,DC=com",
[Parameter(Mandatory=$false)]
[bool]$Enabled = $true,
[Parameter(Mandatory=$false)]
[string]$LogPath = ".\ad_management.log"
)
$ErrorActionPreference = "Stop"
function Write-Log {
param(
[string]$Message,
[ValidateSet('INFO', 'WARNING', 'ERROR')]
[string]$Level = 'INFO'
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "[$timestamp] [$Level] $Message"
Write-Host $logEntry
Add-Content -Path $LogPath -Value $logEntry
}
function Test-ADModule {
try {
Import-Module ActiveDirectory -ErrorAction Stop
return $true
}
catch {
Write-Log "Active Directory module not available. Please install RSAT." -Level 'ERROR'
return $false
}
}
function Validate-Username {
param([string]$Username)
if ([string]::IsNullOrWhiteSpace($Username)) {
throw "Username cannot be empty"
}
if ($Username -match '[\s\\/":|<>+=;,?*@]') {
throw "Username contains invalid characters"
}
if ($Username.Length -gt 20) {
throw "Username exceeds maximum length of 20 characters"
}
return $true
}
function Validate-Email {
param([string]$Email)
if ([string]::IsNullOrWhiteSpace($Email)) {
return $false
}
$emailRegex = '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return $Email -match $emailRegex
}
function New-ADUserAdvanced {
param(
[string]$Username,
[string]$FirstName,
[string]$LastName,
[string]$Email,
[string]$OU,
[bool]$Enabled
)
Write-Log "Creating AD user: $Username" -Level 'INFO'
Validate-Username -Username $Username
$displayName = "$FirstName $LastName"
$samAccountName = $Username
$params = @{
SamAccountName = $samAccountName
UserPrincipalName = "$Username@$((Get-ADDomain).DNSRoot)"
Name = $displayName
GivenName = $FirstName
Surname = $LastName
DisplayName = $displayName
Path = $OU
Enabled = $false
ChangePasswordAtLogon = $true
PasswordNeverExpires = $false
}
if ($Email) {
if (-not (Validate-Email -Email $Email)) {
throw "Invalid email format: $Email"
}
$params.EmailAddress = $Email
}
try {
New-ADUser @params
Write-Log "User $Username created successfully" -Level 'INFO'
if ($Enabled) {
$tempPassword = ConvertTo-SecureString "TempPassword123!" -AsPlainText -Force
Set-ADAccountPassword -Identity $Username -NewPassword $tempPassword -Reset
Enable-ADAccount -Identity $Username
Write-Log "User $Username enabled with temporary password" -Level 'INFO'
}
return @{
Success = $true
Username = $Username
DN = (Get-ADUser $Username).DistinguishedName
}
}
catch {
Write-Log "Failed to create user $Username`: $($_.Exception.Message)" -Level 'ERROR'
return @{
Success = $false
Error = $_.Exception.Message
}
}
}
function Update-ADUserAdvanced {
param(
[string]$Username,
[string]$FirstName,
[string]$LastName,
[string]$Email
)
Write-Log "Updating AD user: $Username" -Level 'INFO'
try {
$user = Get-ADUser -Identity $Username -ErrorAction Stop
$updateParams = @{}
if ($FirstName) {
$updateParams.GivenName = $FirstName
$updateParams.DisplayName = "$FirstName $($user.Surname)"
}
if ($LastName) {
$updateParams.Surname = $LastName
$updateParams.DisplayName = "$($user.GivenName) $LastName"
}
if ($Email) {
if (-not (Validate-Email -Email $Email)) {
throw "Invalid email format: $Email"
}
$updateParams.EmailAddress = $Email
}
if ($updateParams.Count -gt 0) {
Set-ADUser -Identity $Username @updateParams
Write-Log "User $Username updated successfully" -Level 'INFO'
}
else {
Write-Log "No updates provided for user $Username" -Level 'WARNING'
}
return @{
Success = $true
Username = $Username
}
}
catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
Write-Log "User $Username not found" -Level 'ERROR'
return @{
Success = $false
Error = "User not found"
}
}
catch {
Write-Log "Failed to update user $Username`: $($_.Exception.Message)" -Level 'ERROR'
return @{
Success = $false
Error = $_.Exception.Message
}
}
}
function Remove-ADUserAdvanced {
param([string]$Username)
Write-Log "Deleting AD user: $Username" -Level 'INFO'
try {
Remove-ADUser -Identity $Username -Confirm:$false
Write-Log "User $Username deleted successfully" -Level 'INFO'
return @{
Success = $true
Username = $Username
}
}
catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
Write-Log "User $Username not found" -Level 'ERROR'
return @{
Success = $false
Error = "User not found"
}
}
catch {
Write-Log "Failed to delete user $Username`: $($_.Exception.Message)" -Level 'ERROR'
return @{
Success = $false
Error = $_.Exception.Message
}
}
}
function Set-ADUserStatus {
param(
[string]$Username,
[bool]$Enable
)
Write-Log "Setting user $Username status to $(if($Enable){'Enabled'}else{'Disabled'})" -Level 'INFO'
try {
if ($Enable) {
Enable-ADAccount -Identity $Username
}
else {
Disable-ADAccount -Identity $Username
}
Write-Log "User $Username status updated successfully" -Level 'INFO'
return @{
Success = $true
Username = $Username
Enabled = $Enable
}
}
catch {
Write-Log "Failed to update user status $Username`: $($_.Exception.Message)" -Level 'ERROR'
return @{
Success = $false
Error = $_.Exception.Message
}
}
}
function Get-ADUserList {
param(
[string]$Filter = "*",
[string]$SearchBase = (Get-ADDomain).DistinguishedName
)
Write-Log "Listing AD users with filter: $Filter" -Level 'INFO'
try {
$users = Get-ADUser -Filter $Filter -SearchBase $SearchBase -Properties EmailAddress, LastLogonDate, Enabled
$userList = $users | ForEach-Object {
[PSCustomObject]@{
Username = $_.SamAccountName
DisplayName = $_.DisplayName
Email = $_.EmailAddress
Enabled = $_.Enabled
LastLogon = $_.LastLogonDate
DN = $_.DistinguishedName
}
}
return @{
Success = $true
Users = $userList
}
}
catch {
Write-Log "Failed to list users`: $($_.Exception.Message)" -Level 'ERROR'
return @{
Success = $false
Error = $_.Exception.Message
}
}
}
$moduleAvailable = Test-ADModule
if (-not $moduleAvailable) {
exit 1
}
switch ($Action) {
'Create' {
if (-not $Username -or -not $FirstName -or -not $LastName) {
Write-Log "Username, FirstName, and LastName are required for Create action" -Level 'ERROR'
exit 1
}
$result = New-ADUserAdvanced -Username $Username -FirstName $FirstName -LastName $LastName -Email $Email -OU $OU -Enabled $Enabled
}
'Update' {
if (-not $Username) {
Write-Log "Username is required for Update action" -Level 'ERROR'
exit 1
}
$result = Update-ADUserAdvanced -Username $Username -FirstName $FirstName -LastName $LastName -Email $Email
}
'Delete' {
if (-not $Username) {
Write-Log "Username is required for Delete action" -Level 'ERROR'
exit 1
}
$result = Remove-ADUserAdvanced -Username $Username
}
'Disable' {
if (-not $Username) {
Write-Log "Username is required for Disable action" -Level 'ERROR'
exit 1
}
$result = Set-ADUserStatus -Username $Username -Enable $false
}
'Enable' {
if (-not $Username) {
Write-Log "Username is required for Enable action" -Level 'ERROR'
exit 1
}
$result = Set-ADUserStatus -Username $Username -Enable $true
}
'List' {
$result = Get-ADUserList
}
}
if ($result.Success) {
Write-Log "Operation completed successfully" -Level 'INFO'
if ($result.Users) {
$result.Users | Format-Table -AutoSize
}
}
else {
Write-Log "Operation failed: $($result.Error)" -Level 'ERROR'
exit 1
}