dataplat / dbatools

🚀 SQL Server automation and instance migrations have never been safer, faster or freer
https://dbatools.io
MIT License
2.39k stars 787 forks source link

Test-DbaWindowsLogin add property on account name mismatch #9366

Open Cryovenom opened 1 month ago

Cryovenom commented 1 month ago

Summarize Functionality

I'm requesting that Test-DbaWindowsLogin have an additional property added so that it returns a $true/$false value when it detects that the SamAccountName doesn't match the Login name.

The Test-DbaWindowsLogin command already detects this state and pops a nice WARNING about it, but there is no way to query the output of the command to tell that it was detected.

This would allow me to easily find any of these name mismatches in my environment so that I could flag them to be fixed.

Is there a command that is similiar or close to what you are looking for?

Yes

Technical Details

In our environment there are several servers with Logins whose names no longer match their SamAccountName in Active Directory.

When I run Test-DbaWindowsLogin on one of these logins, I get a nice warning message saying WARNING: [12:35:35][Test-DbaWindowsLogin] SamAccountName mismatch detected for (account).

Unfortunately, beyond the warning, I can't actually tell that there's anything wrong with the login from the output of the command.

I'd like to request a property that's something like "SamAccountNameMismatch" with $true/$false value so that when I run Test-DbaWindowsLogin I can do something like:

Test-DbaWindowsLogin -SqlInstance $AllSQLInstances | Where { $_.SamAccountNameMismatch -eq $true }

and find all of the logins in my environment which don't align properly.

Cryovenom commented 1 month ago

If someone is looking for a temporary work-around, here's what I came up with to capture the WARNING and act on it:

# Test the login - store warnings in a variable for parsing and suppress their display to screen
$TestResult = Test-DbaWindowsLogin -SqlInstance $Instance.Name -Login $WinLogin.Name -WarningVariable TestLoginWarnings -WarningAction SilentlyContinue

# Based on the warning message determine if the login was found but had a SamAccountName Mismatch
If ($TestResult.Found -eq $true -And $TestLoginWarnings -Like "*SamAccountName mismatch*"){
    $InstanceSamMisMatchedWinLogins += $WinLogin
}

# Export Logins with SamAccountName Mismatch to CSV for Instance
If ($InstanceSamMisMatchedWinLogins.Count -ne 0){
    $InstanceSamMisMatchedWinLogins | Select SQLInstance,Name,LoginType | Export-CSV "$outputPath\$InstanceNameForOutputFile-SQLLogins-SamMismatch.csv" -NoTypeInformation
}
wsmelton commented 1 month ago

I would agree anything we check on an object should have an associated output property to act upon; reasonable request for sure.

https://github.com/dataplat/dbatools/blob/78c1bc392985541999949f76d2738b316e41a534/public/Test-DbaWindowsLogin.ps1#L173-L202

It wouldn't hurt to have this updated similar to the copy objects that we output. At most include the message as a note or status so there is something showing "why" we set the property to false.

Cryovenom commented 1 month ago

Found isn't set to $false in the event of a SamAccountName mismatch - it's set to $true. That's why my workaround is to check if found -eq $true, then check if there was a warning about a SamAccountName mismatch.

I think setting it to $true is the correct thing to do because technically the account has been found and will work in many cases because it's matched based on SID. If it was set to $false then it would create a risk where anyone who pipes the output of Test-DbaWindowsLogin to Remove-DbaLogin based on a result of $false would remove accounts that technically are working, just mis-labeled.