diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index ff662b3..06db311 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -17,6 +17,10 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic * [#362](https://github.com/Icinga/icinga-powershell-framework/issues/362) Fixes repository component installation from file share locations * [#363](https://github.com/Icinga/icinga-powershell-framework/issues/363) Fixes unneeded continue for JEA process lookup, in case no JEA pid is present +### Enhancements + +* [#364](https://github.com/Icinga/icinga-powershell-framework/pull/364) Fixes a long lookup for the user table on environments with a large Active Directory + ## 1.6.0 (2021-09-07) [Issue and PRs](https://github.com/Icinga/icinga-powershell-framework/milestone/15?closed=1) diff --git a/lib/core/tools/Get-IcingaUserSID.psm1 b/lib/core/tools/Get-IcingaUserSID.psm1 index e96602b..9c3fa8d 100644 --- a/lib/core/tools/Get-IcingaUserSID.psm1 +++ b/lib/core/tools/Get-IcingaUserSID.psm1 @@ -24,12 +24,12 @@ function Get-IcingaUserSID() $NTUser = New-Object System.Security.Principal.NTAccount($UserData.Domain, $UserData.User); $SecurityData = $NTUser.Translate([System.Security.Principal.SecurityIdentifier]); } catch { - throw $_.Exception; + return $null; } } if ($null -eq $SecurityData) { - throw 'Failed to fetch user information from system'; + return $null; } return $SecurityData.Value; diff --git a/lib/core/windows/New-IcingaWindowsUser.psm1 b/lib/core/windows/New-IcingaWindowsUser.psm1 index 366af65..14b4b8d 100644 --- a/lib/core/windows/New-IcingaWindowsUser.psm1 +++ b/lib/core/windows/New-IcingaWindowsUser.psm1 @@ -14,7 +14,12 @@ function New-IcingaWindowsUser() } $UserMetadata = Get-IcingaWindowsUserMetadata; - $UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' | Where-Object { $_.Name -eq $IcingaUser }; + $UserConfig = $null; + + $SID = Get-IcingaUserSID -User $IcingaUser; + if ([string]::IsNullOrEmpty($SID) -eq $FALSE) { + $UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' -Filter ([string]::Format("SID = '{0}'", $SID)); + } if ($null -ne $UserConfig) { @@ -32,6 +37,8 @@ function New-IcingaWindowsUser() } Write-IcingaConsoleNotice 'User updated successfully.'; + } else { + Write-IcingaConsoleWarning 'User "{0}" is not managed by Icinga for Windows. No changes were made.' -Objects $IcingaUser; } return @{ @@ -61,7 +68,8 @@ function New-IcingaWindowsUser() $LocalUserGroup.Add("WinNT://$Env:COMPUTERNAME/$IcingaUser,user") #> - $UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' | Where-Object { $_.Name -eq $IcingaUser }; + $SID = Get-IcingaUserSID -User $IcingaUser; + $UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' -Filter ([string]::Format("SID = '{0}'", $SID)); Write-IcingaConsoleNotice 'User was successfully created.'; diff --git a/lib/core/windows/Remove-IcingaWindowsUser.psm1 b/lib/core/windows/Remove-IcingaWindowsUser.psm1 index ab23a7a..8d0b9a2 100644 --- a/lib/core/windows/Remove-IcingaWindowsUser.psm1 +++ b/lib/core/windows/Remove-IcingaWindowsUser.psm1 @@ -4,21 +4,26 @@ function Remove-IcingaWindowsUser() $IcingaUser = 'icinga' ); - $UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' | Where-Object { $_.Name -eq $IcingaUser }; + $SID = Get-IcingaUserSID -User $IcingaUser; if ((Test-IcingaManagedUser -IcingaUser $IcingaUser) -eq $FALSE) { Write-IcingaConsoleNotice 'The user "{0}" is not present or not created by Icinga for Windows. Unable to remove user' -Objects $IcingaUser; - return; + + return @{ + 'User' = $IcingaUser; + 'SID' = $SID; + }; } - $Result = Start-IcingaProcess -Executable 'net' -Arguments ([string]::Format('user "{0}" /DELETE', $IcingaUser)); + $UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' -Filter ([string]::Format("SID = '{0}'", $SID)); + $Result = Start-IcingaProcess -Executable 'net' -Arguments ([string]::Format('user "{0}" /DELETE', $UserConfig.Name)); if ($Result.ExitCode -ne 0) { Write-IcingaConsoleError 'Failed to delete user "{0}": {1}' -Objects $IcingaUser, $Result.Error; } else { # Delete Home Directory $HomePath = Join-Path -Path ($ENV:HOMEDRIVE) -ChildPath (Join-Path -Path '\Users\' -ChildPath $IcingaUser); - Remove-ItemSecure -Path $HomePath -Recurse -Force; + Remove-ItemSecure -Path $HomePath -Recurse -Force | Out-Null; } return @{ diff --git a/lib/core/windows/Test-IcingaManagedUser.psm1 b/lib/core/windows/Test-IcingaManagedUser.psm1 index 4a174d9..c33b65c 100644 --- a/lib/core/windows/Test-IcingaManagedUser.psm1 +++ b/lib/core/windows/Test-IcingaManagedUser.psm1 @@ -5,18 +5,15 @@ function Test-IcingaManagedUser() [string]$SID ); - $UserData = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' | Where-Object { $_.Name -eq $IcingaUser }; - $FullUserData = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' | Where-Object { $_.Caption.ToLower() -eq $IcingaUser.ToLower() }; - - if ($null -eq $FullUserData -And $null -eq $UserData -And [string]::IsNullOrEmpty($SID)) { - return $FALSE; - } - if ([string]::IsNullOrEmpty($SID)) { $SID = Get-IcingaUserSID -User $IcingaUser; } - $UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' | Where-Object { $_.SID -eq $SID }; + if ([string]::IsNullOrEmpty($SID)) { + return $FALSE; + } + + $UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' -Filter ([string]::Format("SID = '{0}'", $SID)); $UserMetadata = Get-IcingaWindowsUserMetadata; if ($null -eq $UserConfig -Or $UserConfig.FullName -ne $UserMetadata.FullName -Or $UserConfig.Description -ne $UserMetadata.Description) { diff --git a/lib/core/windows/Update-IcingaServiceUser.psm1 b/lib/core/windows/Update-IcingaServiceUser.psm1 index e62b90b..c4495c8 100644 --- a/lib/core/windows/Update-IcingaServiceUser.psm1 +++ b/lib/core/windows/Update-IcingaServiceUser.psm1 @@ -11,7 +11,7 @@ function Update-IcingaServiceUser() } $SID = Get-IcingaUserSID -User $IcingaUser; - $UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' | Where-Object { $_.SID -eq $SID }; + $UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' -Filter ([string]::Format("SID = '{0}'", $SID)); $User = New-IcingaWindowsUser -IcingaUser $UserConfig.Name; Set-IcingaServiceUser -User $IcingaUser -Password $Global:Icinga.ServiceUserPassword -Service 'icinga2' | Out-Null;