202 lines
11 KiB
PowerShell
202 lines
11 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 = ""
|
||
|
# We need to use their stupid [Amazon.EC2.Model.Tag], so we have to import their module.
|
||
|
Import-Module AWSPowerShell
|
||
|
|
||
|
Mock -CommandName Get-LogLeadName -ModuleName $moduleForMock -MockWith { return 'Get-TerminatedComputersReport.tests' }
|
||
|
Mock -CommandName Write-Progress -ModuleName $moduleForMock -MockWith {}
|
||
|
Mock -CommandName Import-Module -ModuleName $moduleForMock -MockWith {}
|
||
|
Mock -CommandName Get-Date -ModuleName $moduleForMock -MockWith {return ([datetime]::Now)}
|
||
|
Mock -CommandName Write-Error -ModuleName $moduleForMock -MockWith {}
|
||
|
Mock -CommandName Test-IsTeamCityProcess -ModuleName $moduleForMock -MockWith { return $false }
|
||
|
|
||
|
|
||
|
$credential = ([pscredential]::new("test",("test1" | ConvertTo-SecureString -AsPlainText -Force)))
|
||
|
|
||
|
Describe "Get-TerminatedComputersReport" {
|
||
|
Context "When a parameter value is not valid or missing" {
|
||
|
It "Throws an exception if Credential parameter is blank" {
|
||
|
{ Get-TerminatedComputersReport -Credential -Domain fh.local } | Should -Throw
|
||
|
}
|
||
|
|
||
|
It "Throws an exception if Domain parameter is blank" {
|
||
|
{ Get-TerminatedComputersReport -Credential $credential -Domain } | Should -Throw
|
||
|
}
|
||
|
|
||
|
It "Throws an exception if OU is not provided a value" {
|
||
|
{ Get-TerminatedComputersReport -OU } | Should -Throw
|
||
|
}
|
||
|
|
||
|
It "Throws an exception if NumberOfDays is not provided a value" {
|
||
|
{ Get-TerminatedComputersReport -NumberOfDays } | Should -Throw
|
||
|
}
|
||
|
|
||
|
It "Throws an exception if NumberOfDays is outside of the valid range" {
|
||
|
{ Get-TerminatedComputersReport -NumberOfDays 366 } | Should -Throw
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Context "Error Handling"{
|
||
|
It "Writes an error if AWSPowerShell cannot be loaded" {
|
||
|
Mock -CommandName Get-Module -ModuleName $moduleForMock -MockWith {[pscustomobject]@{"Name" = "NotAWSPowerShell"}}
|
||
|
Mock -CommandName Import-Module -ModuleName $moduleForMock -MockWith { throw "Module not found."}
|
||
|
|
||
|
Get-TerminatedComputersReport -CheckAWS
|
||
|
|
||
|
Assert-MockCalled -CommandName Write-Error -Times 1 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*Unable to load the AWSPowerShell module*"}
|
||
|
}
|
||
|
|
||
|
It "Writes an error if DNS for the domain cannot be resolved" {
|
||
|
Mock -CommandName Resolve-DnsName -ModuleName $moduleForMock -MockWith { throw "It's always DNS."}
|
||
|
|
||
|
Get-TerminatedComputersReport -Credential $credential -Domain fh.local
|
||
|
|
||
|
Assert-MockCalled -CommandName Write-Error -Times 1 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*Error when resolving DNS for*"}
|
||
|
}
|
||
|
|
||
|
It "Writes an error if bad credentials are supplied" {
|
||
|
Mock -CommandName Resolve-DnsName -ModuleName $moduleForMock -MockWith { return [pscustomobject]@{"IPAddress"="10.0.0.1"} }
|
||
|
Mock -CommandName Test-Connection -ModuleName $moduleForMock -MockWith { return [pscustomobject]@{"Address"="10.0.0.1";"ResponseTime" = 25} }
|
||
|
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith { throw [System.Security.Authentication.AuthenticationException]::new("The server has rejected the client credentials.") }
|
||
|
|
||
|
Get-TerminatedComputersReport -Credential $credential -Domain fh.local
|
||
|
|
||
|
Assert-MockCalled -CommandName Write-Error -Times 1 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*Unable to connect to the target domain, invalid credentials*"}
|
||
|
}
|
||
|
|
||
|
It "Writes an error if unable to retrieve AD Computer objects" {
|
||
|
Mock -CommandName Resolve-DnsName -ModuleName $moduleForMock -MockWith { return [pscustomobject]@{"IPAddress"="10.0.0.1"} }
|
||
|
Mock -CommandName Test-Connection -ModuleName $moduleForMock -MockWith { return [pscustomobject]@{"Address"="10.0.0.1";"ResponseTime" = 25} }
|
||
|
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith { throw "Something bad happened"}
|
||
|
|
||
|
Get-TerminatedComputersReport -Credential $credential -Domain fh.local
|
||
|
|
||
|
Assert-MockCalled -CommandName Write-Error -Times 1 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*Unable to retrieve Computer objects from AD*"}
|
||
|
}
|
||
|
|
||
|
It "Writes an error if unable to retrieve EC2 instances from us-east-1" {
|
||
|
Mock -CommandName Get-Module -ModuleName $moduleForMock -MockWith {[pscustomobject]@{"Name" = "AWSPowerShell"}}
|
||
|
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith {}
|
||
|
Mock -CommandName Get-EC2Instance -ModuleName $moduleForMock -ParameterFilter { $Region -eq "us-east-1"} -MockWith {throw "Error getting EC2 in us-east-1"}
|
||
|
|
||
|
Get-TerminatedComputersReport -CheckAWS
|
||
|
|
||
|
Assert-MockCalled -CommandName Write-Error -Times 4 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*An error occurred while retrieving EC2 instances in us-east-1*"}
|
||
|
}
|
||
|
|
||
|
It "Writes an error if unable to retrieve EC2 instances from us-west-2"{
|
||
|
Mock -CommandName Get-Module -ModuleName $moduleForMock -MockWith {[pscustomobject]@{"Name" = "AWSPowerShell"}}
|
||
|
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith {}
|
||
|
Mock -CommandName Get-EC2Instance -ModuleName $moduleForMock -ParameterFilter { $Region -eq "us-east-1"} -MockWith {}
|
||
|
Mock -CommandName Get-EC2Instance -ModuleName $moduleForMock -ParameterFilter { $Region -eq "us-west-2"} -MockWith {throw "Error getting EC2 in us-west-2"}
|
||
|
|
||
|
Get-TerminatedComputersReport -CheckAWS
|
||
|
|
||
|
Assert-MockCalled -CommandName Get-EC2Instance -Times 5 -Exactly -ModuleName $moduleForMock -Scope It
|
||
|
Assert-MockCalled -CommandName Write-Error -Times 1 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*An error occurred while retrieving EC2 instances in us-west-2*"}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Context "Returns results" {
|
||
|
$testDate = Get-Date
|
||
|
It "Returns results without comparing to AWS" {
|
||
|
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith {
|
||
|
return (
|
||
|
[pscustomobject]@{
|
||
|
"Name" = "TestComputerName"
|
||
|
"Enabled" = $true
|
||
|
"IPv4Address" = "10.0.0.2"
|
||
|
"lastLogonDate" = $testDate
|
||
|
"PasswordLastSet" = $testDate
|
||
|
"SID" = "The-Sloth"
|
||
|
}
|
||
|
)
|
||
|
}
|
||
|
|
||
|
$adOnlyTest = Get-TerminatedComputersReport
|
||
|
$expected = [pscustomobject]@{
|
||
|
"ADName" = "TestComputerName"
|
||
|
"IsEnabled" = $true
|
||
|
"ADIPv4Address" = "10.0.0.2"
|
||
|
"LastLogon" = $testDate
|
||
|
"PasswordLastSet" = $testDate
|
||
|
"SID" = "The-Sloth"
|
||
|
"TerminationConfidence" = [byte](($testDate) -lt ($testDate).AddDays(-90))
|
||
|
}
|
||
|
(($adOnlyTest).ADName -eq ($expected).ADName) | Should -BeTrue
|
||
|
(($adOnlyTest).IsEnabled -eq ($expected).IsEnabled) | Should -BeTrue
|
||
|
(($adOnlyTest).ADIPv4Address -eq ($expected).ADIPv4Address) | Should -BeTrue
|
||
|
(($adOnlyTest).LastLogon -eq ($expected).LastLogon) | Should -BeTrue
|
||
|
(($adOnlyTest).PasswordLastSet -eq ($expected).PasswordLastSet) | Should -BeTrue
|
||
|
(($adOnlyTest).SID -eq ($expected).SID) | Should -BeTrue
|
||
|
(($adOnlyTest).TerminationConfidence -eq ($expected).TerminationConfidence) | Should -BeTrue
|
||
|
}
|
||
|
|
||
|
It "Returns results comparing to AWS" {
|
||
|
Mock -CommandName Get-Module -ModuleName $moduleForMock -MockWith {[pscustomobject]@{"Name" = "AWSPowerShell"}}
|
||
|
$script:mockCalled = 0
|
||
|
$getEC2InstanceMock = {
|
||
|
$script:mockCalled++
|
||
|
if($script:mockCalled -eq 1){
|
||
|
# This is a hot mess, but we are trying to replicate the blackmagic that AWS has created when returning these objects
|
||
|
return (
|
||
|
@{"Instances"=[pscustomobject]@{
|
||
|
"InstanceId" = "i-AmTheSloth"
|
||
|
"PrivateIPAddress" = "10.0.0.2"
|
||
|
"tags" = @([Amazon.EC2.Model.Tag]::new("alk:hostname","TestComputerName"),[Amazon.EC2.Model.Tag]::new("alk:designation","1000"))
|
||
|
}
|
||
|
}
|
||
|
)
|
||
|
} else {
|
||
|
return $null
|
||
|
}
|
||
|
}
|
||
|
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith {
|
||
|
return (
|
||
|
[pscustomobject]@{
|
||
|
"Name" = "TestComputerName"
|
||
|
"Enabled" = $true
|
||
|
"IPv4Address" = "10.0.0.2"
|
||
|
"lastLogonDate" = $testDate
|
||
|
"PasswordLastSet" = $testDate
|
||
|
"SID" = "The-Sloth"
|
||
|
}
|
||
|
)
|
||
|
}
|
||
|
Mock -CommandName Get-EC2Instance -ModuleName $moduleForMock -MockWith $getEC2InstanceMock
|
||
|
|
||
|
$awsTest = Get-TerminatedComputersReport -CheckAWS
|
||
|
$expected = [pscustomobject]@{
|
||
|
"ADName" = "TestComputerName"
|
||
|
"IsEnabled" = $true
|
||
|
"ADIPv4Address" = "10.0.0.2"
|
||
|
"LastLogon" = $testDate
|
||
|
"PasswordLastSet" = $testDate
|
||
|
"SID" = "The-Sloth"
|
||
|
"InstanceIdByIP" = "i-AmTheSloth"
|
||
|
"InstanceIdByName" = "i-AmTheSloth"
|
||
|
"DoesInstanceMatch" = $true
|
||
|
"Designation" = "1000"
|
||
|
"TerminationConfidence" = 0
|
||
|
}
|
||
|
|
||
|
(($awsTest).ADName -eq ($expected).ADName) | Should -BeTrue
|
||
|
(($awsTest).IsEnabled -eq ($expected).IsEnabled) | Should -BeTrue
|
||
|
(($awsTest).ADIPv4Address -eq ($expected).ADIPv4Address) | Should -BeTrue
|
||
|
(($awsTest).LastLogon -eq ($expected).LastLogon) | Should -BeTrue
|
||
|
(($awsTest).PasswordLastSet -eq ($expected).PasswordLastSet) | Should -BeTrue
|
||
|
(($awsTest).SID -eq ($expected).SID) | Should -BeTrue
|
||
|
(($awsTest).InstanceIdByIP -eq ($expected).InstanceIdByIP) | Should -BeTrue
|
||
|
(($awsTest).InstanceIdByName -eq ($expected).InstanceIdByName) | Should -BeTrue
|
||
|
(($awsTest).DoesInstanceMatch -eq ($expected).DoesInstanceMatch) | Should -BeTrue
|
||
|
(($awsTest).Designation -eq ($expected).Designation) | Should -BeTrue
|
||
|
(($awsTest).TerminationConfidence -eq ($expected).TerminationConfidence) | Should -BeTrue
|
||
|
}
|
||
|
}
|
||
|
}
|