ps/Modules/Alkami.PowerShell.Services/Public/Clear-GMSAPasswords.tests.ps1
2023-05-30 22:51:22 -07:00

228 lines
13 KiB
PowerShell

. $PSScriptRoot\..\..\Load-PesterModules.ps1
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.tests\.', '.'
$functionPath = Join-Path -Path $here -ChildPath $sut
Write-Host "Overriding SUT: $functionPath"
Import-Module $functionPath -Force
$moduleForMock = ""
Describe "Clear-GMSAPasswords" {
Context "Error Handling" {
It "Writes a Warning and Returns if No Services Found" {
Mock -CommandName Get-ChocolateyServices -MockWith { return @() } -ModuleName $moduleForMock
Mock -CommandName Get-AlkamiServices -MockWith { return @() } -ModuleName $moduleForMock
Mock -CommandName Write-Warning -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Get-WindowsServiceUser -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Invoke-SCExe -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Set-ServiceAccountManagedState -MockWith {} -ModuleName $moduleForMock
Clear-GMSAPasswords
# Assert the Warning is Written
Assert-MockCalled -CommandName Write-Warning -Times 1 -Exactly -Scope It -ModuleName $moduleForMock -ParameterFilter { $Message -match "Found no Services" }
# Assert No Calls to Invoke-SCExe are made when no services are found
Assert-MockCalled -CommandName Invoke-SCExe -Times 0 -Exactly -Scope It -ModuleName $moduleForMock
}
It "Writes a Warning and Skips Services Not Running as GMSA Accounts" {
Mock -CommandName Get-ChocolateyServices -MockWith { return @( New-Object PSObject -Property @{ Name="Super.Fake.Awesome.Service"; } ) } -ModuleName $moduleForMock
Mock -CommandName Get-AlkamiServices -MockWith { return @( New-Object PSObject -Property @{ Name="Other.Fake.Awesome.Nag.Service"; } ) } -ModuleName $moduleForMock
Mock -CommandName Get-WindowsServiceUser -MockWith { return "FH\fake.User" } -ModuleName $moduleForMock
Mock -CommandName Write-Warning -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Invoke-SCExe -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Set-ServiceAccountManagedState -MockWith {} -ModuleName $moduleForMock
Clear-GMSAPasswords
# Assert that a warning is written for both Choco and Legacy services
Assert-MockCalled -CommandName Write-Warning -Times 2 -Exactly -Scope It -ModuleName $moduleForMock -ParameterFilter { $Message -match "Skipping Service" }
# Assert No Calls to Invoke-SCExe are made when no services are found running under gMSA context
Assert-MockCalled -CommandName Invoke-SCExe -Times 0 -Exactly -Scope It -ModuleName $moduleForMock
}
It "Writes a Warning if Services Were Found But None Match the Filter List Parameter" {
Mock -CommandName Get-ChocolateyServices -MockWith { return @( New-Object PSObject -Property @{ Name="Super.Fake.Awesome.Service"; } ) } -ModuleName $moduleForMock
Mock -CommandName Get-AlkamiServices -MockWith { return @( New-Object PSObject -Property @{ Name="Super.Fake.Radium.Service"; } ) } -ModuleName $moduleForMock
Mock -CommandName Write-Warning -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Invoke-SCExe -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Set-ServiceAccountManagedState -MockWith {} -ModuleName $moduleForMock
Clear-GMSAPasswords "NonExistent Service!"
# Assert that a warning is written because no services are found matching the supplied filter
Assert-MockCalled -CommandName Write-Warning -Times 1 -Exactly -Scope It -ModuleName $moduleForMock -ParameterFilter { $Message -match "Found no matching services" }
# Assert No Calls to Invoke-SCExe are made when no matching services are found
Assert-MockCalled -CommandName Invoke-SCExe -Times 0 -Exactly -Scope It -ModuleName $moduleForMock
}
}
Context "External Calls" {
It "Calls Set-ServiceAccountManagedState for Each Service When No Service Filter Supplied" {
Mock -CommandName Get-WindowsServiceUser -MockWith { return "FH\fake.User$" } -ModuleName $moduleForMock
Mock -CommandName Get-AlkamiServices -MockWith { return @() } -ModuleName $moduleForMock
Mock -CommandName Invoke-SCExe -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Write-Verbose -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Set-ServiceAccountManagedState -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Get-ChocolateyServices -ModuleName $moduleForMock -MockWith {
return @(
(New-Object PSObject -Property @{
Name="Super.Fake.Awesome.Service";
}),
(New-Object PSObject -Property @{
Name="NotSoSuper.Fake.Sucky.Service";
})
)
}
Clear-GMSAPasswords
# Make sure Set-ServiceAccountManagedState was called for each service
Assert-MockCalled -CommandName Set-ServiceAccountManagedState -Times 2 -Exactly -Scope It
# Make sure Set-ServiceAccountManagedState was called with the expected service name filters
Assert-MockCalled -CommandName Set-ServiceAccountManagedState -Times 1 -Exactly -Scope It -ModuleName $moduleForMock `
-ParameterFilter { $ServiceName -match "Super.Fake.Awesome.Service" }
Assert-MockCalled -CommandName Set-ServiceAccountManagedState -Times 1 -Exactly -Scope It -ModuleName $moduleForMock `
-ParameterFilter { $ServiceName -match "NotSoSuper.Fake.Sucky.Service" }
}
It "Correctly Filters Set-ServiceAccountManagedState Based on a Supplied Service Name String" {
Mock -CommandName Get-WindowsServiceUser -MockWith { return "FH\fake.User$" } -ModuleName $moduleForMock
Mock -CommandName Get-AlkamiServices -MockWith { return @() } -ModuleName $moduleForMock
Mock -CommandName Invoke-SCExe -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Write-Verbose -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Set-ServiceAccountManagedState -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Get-ChocolateyServices -ModuleName $moduleForMock -MockWith {
return @(
(New-Object PSObject -Property @{
Name="Super.Fake.Awesome.Service";
}),
(New-Object PSObject -Property @{
Name="NotSoSuper.Fake.Sucky.Service";
})
)
}
Clear-GMSAPasswords "Super.Fake.Awesome.Service"
# Make sure Set-ServiceAccountManagedState was only called once
Assert-MockCalled -CommandName Set-ServiceAccountManagedState -Times 1 -Exactly -Scope It
# Make sure Set-ServiceAccountManagedState was called with the expected service name filter
Assert-MockCalled -CommandName Set-ServiceAccountManagedState -Times 1 -Exactly -Scope It -ModuleName $moduleForMock `
-ParameterFilter { $ServiceName -match "Super.Fake.Awesome.Service" }
}
}
Context "Parameter Handling" {
It "Correctly Filters Based on a Supplied Service Name String" {
Mock -CommandName Get-WindowsServiceUser -MockWith { return "FH\fake.User$" } -ModuleName $moduleForMock
Mock -CommandName Get-AlkamiServices -MockWith { return @() } -ModuleName $moduleForMock
Mock -CommandName Invoke-SCExe -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Write-Verbose -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Set-ServiceAccountManagedState -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Get-ChocolateyServices -ModuleName $moduleForMock -MockWith {
return @(
(New-Object PSObject -Property @{
Name="Super.Fake.Awesome.Service";
}),
(New-Object PSObject -Property @{
Name="NotSoSuper.Fake.Sucky.Service";
})
)
}
Clear-GMSAPasswords "Super.Fake.Awesome.Service" -Verbose
# Assert that Invoke-SCExe is only called once due to the supplied service name filter
Assert-MockCalled -CommandName Invoke-SCExe -Times 1 -Exactly -Scope It -ModuleName $moduleForMock
# Make sure Invoke-SCExe was called with the expected service name filter
Assert-MockCalled -CommandName Invoke-SCExe -Times 1 -Exactly -Scope It -ModuleName $moduleForMock `
-ParameterFilter { $Arguments -contains "Super.Fake.Awesome.Service" }
# Assert that we write a verbose message indicating the other service was skipped
Assert-MockCalled -CommandName Write-Verbose -Times 1 -Exactly -Scope It -ModuleName $moduleForMock -ParameterFilter { $Message -match "Skipping Service NotSoSuper.Fake.Sucky.Service" }
}
It "Correctly Filters Based on a Service Name Array" {
Mock -CommandName Get-WindowsServiceUser -MockWith { return "FH\fake.User$" } -ModuleName $moduleForMock
Mock -CommandName Get-AlkamiServices -MockWith { return @() } -ModuleName $moduleForMock
Mock -CommandName Invoke-SCExe -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Write-Verbose -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Set-ServiceAccountManagedState -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Get-ChocolateyServices -ModuleName $moduleForMock -MockWith {
return @(
(New-Object PSObject -Property @{
Name="Super.Fake.Awesome.Service";
}),
(New-Object PSObject -Property @{
Name="Yet.Another.Awesome.Service";
}),
(New-Object PSObject -Property @{
Name="NotSoSuper.Fake.Sucky.Service";
})
)
}
Clear-GMSAPasswords @("Super.Fake.Awesome.Service","Yet.Another.Awesome.Service") -Verbose
# Assert that Invoke-SCExe was called twice for both services in the array param
Assert-MockCalled -CommandName Invoke-SCExe -Times 2 -Exactly -Scope It -ModuleName $moduleForMock
# Make sure Invoke-SCExe was called with the expected service name filter
Assert-MockCalled -CommandName Invoke-SCExe -Times 1 -Exactly -Scope It -ModuleName $moduleForMock `
-ParameterFilter { $Arguments -contains "Super.Fake.Awesome.Service" }
Assert-MockCalled -CommandName Invoke-SCExe -Times 1 -Exactly -Scope It -ModuleName $moduleForMock `
-ParameterFilter { $Arguments -contains "Yet.Another.Awesome.Service" }
# Assert that we write a verbose message indicating the other service was skipped
Assert-MockCalled -CommandName Write-Verbose -Times 1 -Exactly -Scope It -ModuleName $moduleForMock -ParameterFilter { $Message -match "Skipping Service NotSoSuper.Fake.Sucky.Service" }
}
It "Only Acts on Unique Service Names Once" {
Mock -CommandName Get-WindowsServiceUser -MockWith { return "FH\fake.User$" } -ModuleName $moduleForMock
Mock -CommandName Invoke-SCExe -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Write-Verbose -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Set-ServiceAccountManagedState -MockWith {} -ModuleName $moduleForMock
Mock -CommandName Get-AlkamiServices -ModuleName $moduleForMock -MockWith {
return New-Object PSObject -Property @{
Name="Super.Fake.Awesome.Service";
}
}
Mock -CommandName Get-ChocolateyServices -ModuleName $moduleForMock -MockWith {
return New-Object PSObject -Property @{
Name="Super.Fake.Awesome.Service";
}
}
Clear-GMSAPasswords @("Super.Fake.Awesome.Service")
# Assert that Invoke-SCExe is only called once though the same service name was returned by both
# Get-AlkamiServices and Get-ChocolateyServices
Assert-MockCalled -CommandName Invoke-SCExe -Times 1 -Exactly -Scope It -ModuleName $moduleForMock
}
}
}