228 lines
13 KiB
PowerShell
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
|
|
}
|
|
}
|
|
} |