183 lines
6.1 KiB
PowerShell
183 lines
6.1 KiB
PowerShell
|
Function Clear-BadPesterUserAccounts {
|
||
|
<#
|
||
|
.SYNOPSIS
|
||
|
Cleans up all incorrectly created user accounts on the system from Pester.
|
||
|
|
||
|
.EXAMPLE
|
||
|
Clear-BadPesterUserAccounts
|
||
|
|
||
|
.OUTPUTS
|
||
|
Returns the list of folder names (from C:\Users) that are "invalid".
|
||
|
If the return list is empty then there were none to remove.
|
||
|
This is useful for post-facto additional resource cleanup. In the case of a non-WhatIf, this will be an ephemeral response, so catch it while you can.
|
||
|
|
||
|
.PARAMETER AllPossibleDomainsToSearch
|
||
|
What domains do we want to search? Defaults to [fh, corp]
|
||
|
|
||
|
.PARAMETER WhatIf
|
||
|
Used to test before removing for validation
|
||
|
#>
|
||
|
param(
|
||
|
$AllPossibleDomainsToSearch = @("fh","corp"),
|
||
|
[switch]$WhatIf
|
||
|
)
|
||
|
|
||
|
$logLead = (Get-LogLeadName)
|
||
|
|
||
|
# This means we are on Windows
|
||
|
# At the very least, we can't get the CIM Instances to remove users if they exist
|
||
|
if ($null -eq (Get-Command Get-CimInstance -ErrorAction SilentlyContinue)) {
|
||
|
Write-Host "$logLead : Can't CimInstance on this host, nothing to do"
|
||
|
return
|
||
|
}
|
||
|
|
||
|
Write-Host "$logLead : Cleaning bad pester user accounts [Dry run? $WhatIf]"
|
||
|
|
||
|
# Get local user accounts
|
||
|
# Get IIS user accounts or IIS app pool names (it defaults the identity to the name if no identity specified)
|
||
|
# Get all domain GMSA accounts
|
||
|
# Get all domain user accounts
|
||
|
#
|
||
|
# Get all c:\users folders
|
||
|
# Diff the names
|
||
|
# Remove the users
|
||
|
|
||
|
# Annoying bug...
|
||
|
if ($null -ne (Get-Module Carbon)) {
|
||
|
# Carbon stomps all over our Get-ADDomainController amongst other things
|
||
|
Remove-Module Carbon -Force
|
||
|
}
|
||
|
|
||
|
$userAccountsToExclude = @()
|
||
|
$foldersToKeep = @()
|
||
|
$foldersToRemove = @()
|
||
|
|
||
|
# The system can't determine about some of these, they are special folders
|
||
|
# This is where any such folders go
|
||
|
# Try to make them dynamic before adding them here.
|
||
|
# Public is a very special child unrelated to anything else.
|
||
|
$userAccountsToExclude += "Public"
|
||
|
|
||
|
if ($null -ne (Get-Module -ListAvailable -Name WebAdministration)) {
|
||
|
Get-Module WebAdministration | Remove-Module -Force
|
||
|
Import-Module WebAdministration
|
||
|
$appPools = @(Get-ChildItem IIS:\AppPools)
|
||
|
foreach($appPool in $appPools) {
|
||
|
if (![string]::IsNullOrWhiteSpace($appPool.processModel.userName)) {
|
||
|
$userAccountsToExclude += $appPool.processModel.userName
|
||
|
} else {
|
||
|
$userAccountsToExclude += $appPool.Name
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$localUsers = @(Get-LocalUser)
|
||
|
foreach($localUser in $localUsers) {
|
||
|
$userAccountsToExclude += $localUser.Name
|
||
|
}
|
||
|
|
||
|
if ($null -eq (Get-Module -ListAvailable -Name ActiveDirectory)) {
|
||
|
# This is truly an impossible condition to hit. So if we hit it, hit it hard.
|
||
|
throw 'how in the name of sanity is this server not setup to query the domain???'
|
||
|
}
|
||
|
|
||
|
Import-Module ActiveDirectory
|
||
|
foreach($domainName in $AllPossibleDomainsToSearch) {
|
||
|
$dc = Get-ADDomainController -DomainName $domainName -Discover -NextClosestSite
|
||
|
|
||
|
$dcHostname = $dc.Hostname[0]
|
||
|
|
||
|
if ([string]::IsNullOrWhiteSpace($dcHostname)) {
|
||
|
Write-Warning "$logLead : Could not find a hostname for $domainName - Can you access that domain from here?"
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
$domainServiceAccounts = @(Get-ADServiceAccount -Filter "*" -Server $dcHostname)
|
||
|
foreach($domainServiceAccount in $domainServiceAccounts) {
|
||
|
$userAccountsToExclude += $domainServiceAccount.SamAccountName
|
||
|
}
|
||
|
|
||
|
$domainUserAccounts = @(Get-ADUser -Filter "*" -Server $dcHostname)
|
||
|
foreach($domainUserAccount in $domainUserAccounts) {
|
||
|
$userAccountsToExclude += $domainUserAccount.SamAccountName
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$userFolders = @(Get-ChildItem -Directory -Path C:\Users)
|
||
|
foreach($folder in $userFolders) {
|
||
|
if ($userAccountsToExclude -contains $folder.Name) {
|
||
|
$foldersToKeep += $folder.Name
|
||
|
} else {
|
||
|
$foldersToRemove += $folder.Name
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$allCimAccounts = @(Get-CimInstance -ClassName Win32_UserProfile)
|
||
|
|
||
|
$teamCity = (Test-IsTeamCityProcess)
|
||
|
|
||
|
if ($teamCity) {
|
||
|
Write-Host "##teamcity[blockOpened name='Display accounts for followup']"
|
||
|
} else {
|
||
|
Write-Host "================================="
|
||
|
}
|
||
|
|
||
|
if (!(Test-IsCollectionNullOrEmpty $foldersToKeep)) {
|
||
|
$tcBlurb = "Keep these accounts"
|
||
|
if ($teamCity) {
|
||
|
Write-Host "##teamcity[blockOpened name='$tcBlurb']"
|
||
|
} else {
|
||
|
Write-Host "$logLead : Found these folders to KEEP"
|
||
|
}
|
||
|
|
||
|
foreach($folder in $foldersToKeep) {
|
||
|
if ($teamCity) {
|
||
|
Write-Host "$logLead : KEEP C:\Users\$folder"
|
||
|
} else {
|
||
|
Write-Verbose "$logLead : KEEP C:\Users\$folder"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ($teamCity) {
|
||
|
Write-Host "##teamcity[blockClosed name='$tcBlurb']"
|
||
|
} else {
|
||
|
Write-Host "================================="
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!(Test-IsCollectionNullOrEmpty $foldersToRemove)) {
|
||
|
$tcBlurb = "Remove these accounts"
|
||
|
if ($teamCity) {
|
||
|
Write-Host "##teamcity[blockOpened name='$tcBlurb']"
|
||
|
} else {
|
||
|
Write-Host "$logLead : Found these folders to REMOVE"
|
||
|
}
|
||
|
|
||
|
foreach($folder in $foldersToRemove) {
|
||
|
Write-Host "$logLead : REMOVE C:\Users\$folder"
|
||
|
$matchingCimInstances = @($allCimAccounts.Where({$_.LocalPath -eq "C:\Users\$folder"}))
|
||
|
|
||
|
foreach($instance in $matchingCimInstances) {
|
||
|
if ($instance.Sid.StartsWith("S-1-5-82")) {
|
||
|
Write-Host "$logLead : $folder is an IIS-AppPool SID"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$matchingCimInstances | Remove-CimInstance -WhatIf:$WhatIf
|
||
|
}
|
||
|
|
||
|
if ($teamCity) {
|
||
|
Write-Host "##teamcity[blockClosed name='$tcBlurb']"
|
||
|
} else {
|
||
|
Write-Host ""
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ($teamCity) {
|
||
|
Write-Host "##teamcity[blockClosed name='Display accounts for followup']"
|
||
|
} else {
|
||
|
Write-Host "================================="
|
||
|
}
|
||
|
|
||
|
return $foldersToRemove
|
||
|
}
|