mirror of
https://github.com/PowerShell/PSDscResources
synced 2026-06-21 13:45:29 +00:00
784 lines
40 KiB
PowerShell
784 lines
40 KiB
PowerShell
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')]
|
|
param ()
|
|
|
|
$errorActionPreference = 'Stop'
|
|
Set-StrictMode -Version 'Latest'
|
|
|
|
$script:moduleRootPath = Split-Path -Path $PSScriptRoot -Parent
|
|
$script:testHelpersPath = Join-Path -Path $script:moduleRootPath -ChildPath 'TestHelpers'
|
|
Import-Module -Name (Join-Path -Path $script:testHelpersPath -ChildPath 'CommonTestHelper.psm1')
|
|
|
|
$script:testEnvironment = Enter-DscResourceTestEnvironment `
|
|
-DscResourceModuleName 'PSDscResources' `
|
|
-DscResourceName 'MSFT_WindowsProcess' `
|
|
-TestType 'Unit'
|
|
|
|
try
|
|
{
|
|
InModuleScope 'MSFT_WindowsProcess' {
|
|
|
|
# Mock objects
|
|
$script:validPath1 = 'ValidPath1'
|
|
$script:validPath2 = 'ValidPath2'
|
|
$script:validPath3 = 'ValidPath3'
|
|
$script:invalidPath = 'InvalidPath'
|
|
$script:testUserName = 'TestUserName12345'
|
|
$testPassword = 'StrongOne7.'
|
|
$testSecurePassword = ConvertTo-SecureString -String $testPassword -AsPlainText -Force
|
|
$script:testCredential = New-Object PSCredential ($script:testUserName, $testSecurePassword)
|
|
$script:exceptionMessage = 'Test Invalid Operation Exception'
|
|
|
|
$script:mockProcess1 = @{
|
|
Path = $script:validPath1
|
|
CommandLine = 'C:\temp\test.exe argument1 argument2 argument3'
|
|
Arguments = 'argument1 argument2 argument3'
|
|
ProcessId = 12345
|
|
Id = 12345
|
|
PagedMemorySize64 = 1048
|
|
NonpagedSystemMemorySize64 = 16
|
|
VirtualMemorySize64 = 256
|
|
HandleCount = 50
|
|
}
|
|
|
|
$script:mockProcess2 = @{
|
|
Path = $script:validPath2
|
|
CommandLine = ''
|
|
Arguments = ''
|
|
ProcessId = 54321
|
|
Id = 54321
|
|
PagedMemorySize64 = 2096
|
|
NonpagedSystemMemorySize64 = 8
|
|
VirtualMemorySize64 = 512
|
|
HandleCount = 5
|
|
}
|
|
|
|
$script:mockProcess3 = @{
|
|
Path = $script:validPath1
|
|
CommandLine = 'C:\test.exe arg6'
|
|
Arguments = 'arg6'
|
|
ProcessId = 1111101
|
|
Id = 1111101
|
|
PagedMemorySize64 = 512
|
|
NonpagedSystemMemorySize64 = 32
|
|
VirtualMemorySize64 = 64
|
|
HandleCount = 0
|
|
}
|
|
|
|
$script:mockProcess4 = @{
|
|
Path = $script:validPath1
|
|
CommandLine = 'C:\test.exe arg6'
|
|
Arguments = 'arg6'
|
|
ProcessId = 1111101
|
|
Id = 1111101
|
|
PagedMemorySize64 = 510
|
|
NonpagedSystemMemorySize64 = 16
|
|
VirtualMemorySize64 = 8
|
|
HandleCount = 8
|
|
}
|
|
|
|
$script:errorProcess = @{
|
|
Path = $script:validPath3
|
|
CommandLine = ''
|
|
Arguments = ''
|
|
ProcessId = 77777
|
|
Id = 77777
|
|
PagedMemorySize64 = 0
|
|
NonpagedSystemMemorySize64 = 0
|
|
VirtualMemorySize64 = 0
|
|
HandleCount = 0
|
|
}
|
|
|
|
Describe 'WindowsProcess\Get-TargetResource' {
|
|
Mock -CommandName Expand-Path -MockWith { return $Path }
|
|
Mock -CommandName Get-ProcessCimInstance -MockWith {
|
|
if ($Path -eq $script:validPath1)
|
|
{
|
|
return @($script:mockProcess1, $script:mockProcess3)
|
|
}
|
|
elseif ($Path -eq $script:validPath2)
|
|
{
|
|
return @($script:mockProcess2)
|
|
}
|
|
elseif ($Path -eq $script:validPath3)
|
|
{
|
|
return @($script:errorProcess)
|
|
}
|
|
else
|
|
{
|
|
return @()
|
|
}
|
|
}
|
|
Mock -CommandName Get-Process -MockWith {
|
|
if ($ID -eq $script:mockProcess1.Id)
|
|
{
|
|
return $script:mockProcess1
|
|
}
|
|
elseif ($script:mockProcess2.Id)
|
|
{
|
|
return $script:mockProcess2
|
|
}
|
|
elseif ($script:mockProcess3.Id)
|
|
{
|
|
return $script:mockProcess3
|
|
}
|
|
else
|
|
{
|
|
return $script:errorProcess
|
|
}
|
|
}
|
|
Mock -CommandName New-InvalidOperationException -MockWith { Throw $script:exceptionMessage }
|
|
Mock -CommandName New-InvalidArgumentException -MockWith { Throw $script:exceptionMessage }
|
|
|
|
It 'Should return the correct properties for a process that is Absent' {
|
|
$processArguments = 'TestGetProperties'
|
|
|
|
$getTargetResourceResult = Get-TargetResource -Path $invalidPath `
|
|
-Arguments $processArguments
|
|
|
|
$getTargetResourceResult.Arguments | Should -Be $processArguments
|
|
$getTargetResourceResult.Ensure | Should -Be 'Absent'
|
|
$getTargetResourceResult.Path | Should -Be $invalidPath
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
}
|
|
|
|
It 'Should return the correct properties for one process with a credential' {
|
|
|
|
$getTargetResourceResult = Get-TargetResource -Path $script:validPath2 `
|
|
-Arguments $script:mockProcess2.Arguments `
|
|
-Credential $script:testCredential
|
|
|
|
$getTargetResourceResult.VirtualMemorySize | Should -Be $script:mockProcess2.VirtualMemorySize64
|
|
$getTargetResourceResult.Arguments | Should -Be $script:mockProcess2.Arguments
|
|
$getTargetResourceResult.Ensure | Should -Be 'Present'
|
|
$getTargetResourceResult.PagedMemorySize | Should -Be $script:mockProcess2.PagedMemorySize64
|
|
$getTargetResourceResult.Path | Should -Be $script:mockProcess2.Path
|
|
$getTargetResourceResult.NonPagedMemorySize | Should -Be $script:mockProcess2.NonpagedSystemMemorySize64
|
|
$getTargetResourceResult.HandleCount | Should -Be $script:mockProcess2.HandleCount
|
|
$getTargetResourceResult.ProcessId | Should -Be $script:mockProcess2.ProcessId
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-Process -Exactly 1 -Scope It
|
|
}
|
|
|
|
It 'Should return the correct properties when there are multiple processes' {
|
|
|
|
$getTargetResourceResult = Get-TargetResource -Path $script:validPath1 `
|
|
-Arguments $script:mockProcess1.Arguments
|
|
|
|
$getTargetResourceResult.VirtualMemorySize | Should -Be $script:mockProcess1.VirtualMemorySize64
|
|
$getTargetResourceResult.Arguments | Should -Be $script:mockProcess1.Arguments
|
|
$getTargetResourceResult.Ensure | Should -Be 'Present'
|
|
$getTargetResourceResult.PagedMemorySize | Should -Be $script:mockProcess1.PagedMemorySize64
|
|
$getTargetResourceResult.Path | Should -Be $script:mockProcess1.Path
|
|
$getTargetResourceResult.NonPagedMemorySize | Should -Be $script:mockProcess1.NonpagedSystemMemorySize64
|
|
$getTargetResourceResult.HandleCount | Should -Be $script:mockProcess1.HandleCount
|
|
$getTargetResourceResult.ProcessId | Should -Be $script:mockProcess1.ProcessId
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-Process -Exactly 1 -Scope It
|
|
}
|
|
}
|
|
|
|
Describe 'WindowsProcess\Set-TargetResource' {
|
|
Mock -CommandName Expand-Path -MockWith { return $Path }
|
|
Mock -CommandName Get-ProcessCimInstance -MockWith {
|
|
if ($Path -eq $script:validPath1)
|
|
{
|
|
return @($script:mockProcess1, $script:mockProcess3)
|
|
}
|
|
elseif ($Path -eq $script:validPath2)
|
|
{
|
|
return @($script:mockProcess2)
|
|
}
|
|
elseif ($Path -eq $script:validPath3)
|
|
{
|
|
return @($script:errorProcess)
|
|
}
|
|
else
|
|
{
|
|
return @()
|
|
}
|
|
}
|
|
Mock -CommandName New-InvalidOperationException -MockWith { Throw $script:exceptionMessage }
|
|
Mock -CommandName New-InvalidArgumentException -MockWith { Throw $script:exceptionMessage }
|
|
Mock -CommandName Stop-Process -MockWith { return $null } `
|
|
-ParameterFilter { ($Id -contains $script:mockProcess1.ProcessId) -or `
|
|
($Id -contains $script:mockProcess2.ProcessId) -or `
|
|
($Id -contains $script:mockProcess3.ProcessId) }
|
|
Mock -CommandName Stop-Process -MockWith { return 'error' } `
|
|
-ParameterFilter { $Id -contains $script:errorProcess.ProcessId}
|
|
Mock -CommandName Test-IsRunFromLocalSystemUser -MockWith { return $true }
|
|
Mock -CommandName Wait-ProcessCount -MockWith { return $true }
|
|
|
|
It 'Should not throw when Ensure set to Absent and processes are running' {
|
|
{ Set-TargetResource -Path $script:validPath1 `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Credential $script:testCredential `
|
|
-Ensure 'Absent'
|
|
} | Should -Not -Throw
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Stop-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Wait-ProcessCount -Exactly 1 -Scope It
|
|
}
|
|
|
|
It 'Should not throw when Ensure set to Absent and processes are not running' {
|
|
{ Set-TargetResource -Path $script:invalidPath `
|
|
-Arguments '' `
|
|
-Ensure 'Absent'
|
|
} | Should -Not -Throw
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Stop-Process -Exactly 0 -Scope It
|
|
Assert-MockCalled -CommandName Wait-ProcessCount -Exactly 0 -Scope It
|
|
}
|
|
|
|
It 'Should throw an invalid operation exception when Stop-Process throws an error' {
|
|
{ Set-TargetResource -Path $script:errorProcess.Path `
|
|
-Arguments '' `
|
|
-Ensure 'Absent'
|
|
} | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Stop-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName New-InvalidOperationException -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Wait-ProcessCount -Exactly 0 -Scope It
|
|
}
|
|
|
|
Mock -CommandName Wait-ProcessCount -MockWith { return $false }
|
|
|
|
It 'Should throw an invalid operation exception when there is a problem waiting for the processes' {
|
|
{ Set-TargetResource -Path $script:validPath1 `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Ensure 'Absent'
|
|
} | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Stop-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Wait-ProcessCount -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName New-InvalidOperationException -Exactly 1 -Scope It
|
|
}
|
|
|
|
Mock -CommandName Wait-ProcessCount -MockWith { return $true }
|
|
Mock -CommandName Start-ProcessAsLocalSystemUser -MockWith {}
|
|
|
|
It 'Should not throw when Ensure set to Present and processes are not running and credential passed in' {
|
|
{ Set-TargetResource -Path $script:invalidPath `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Credential $script:testCredential `
|
|
-Ensure 'Present'
|
|
} | Should -Not -Throw
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Test-IsRunFromLocalSystemUser -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Start-ProcessAsLocalSystemUser -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Wait-ProcessCount -Exactly 1 -Scope It
|
|
}
|
|
|
|
Mock -CommandName Start-ProcessAsLocalSystemUser -MockWith {}
|
|
Mock -CommandName Assert-PathArgumentRooted -MockWith {}
|
|
Mock -CommandName Assert-PathArgumentValid -MockWith {}
|
|
|
|
It 'Should throw when Ensure set to Present, processes not running and credential and WorkingDirectory passed' {
|
|
{ Set-TargetResource -Path $script:invalidPath `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Credential $script:testCredential `
|
|
-WorkingDirectory 'test working directory' `
|
|
-Ensure 'Present'
|
|
} | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Test-IsRunFromLocalSystemUser -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Start-ProcessAsLocalSystemUser -Exactly 0 -Scope It
|
|
Assert-MockCalled -CommandName Wait-ProcessCount -Exactly 0 -Scope It
|
|
Assert-MockCalled -CommandName Assert-PathArgumentRooted -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Assert-PathArgumentValid -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName New-InvalidArgumentException -Exactly 1 -Scope It
|
|
}
|
|
|
|
$testErrorRecord = 'test Start-ProcessAsLocalSystemUser error record'
|
|
Mock -CommandName Start-ProcessAsLocalSystemUser -MockWith { Throw $testErrorRecord }
|
|
|
|
It 'Should throw when Ensure set to Present and Start-processAsLocalSystemUser fails' {
|
|
{ Set-TargetResource -Path $script:invalidPath `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Credential $script:testCredential `
|
|
-Ensure 'Present'
|
|
} | Should -Throw -ExpectedMessage $testErrorRecord
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Test-IsRunFromLocalSystemUser -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Start-ProcessAsLocalSystemUser -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Wait-ProcessCount -Exactly 0 -Scope It
|
|
}
|
|
|
|
Mock -CommandName Start-Process -MockWith {}
|
|
|
|
It 'Should not throw when Ensure set to Present and processes are not running and no credential passed' {
|
|
{ Set-TargetResource -Path $script:invalidPath `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Ensure 'Present'
|
|
} | Should -Not -Throw
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Start-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Wait-ProcessCount -Exactly 1 -Scope It
|
|
}
|
|
|
|
$mockStartProcessException = New-Object -TypeName 'InvalidOperationException' `
|
|
-ArgumentList @('Start-Process test exception')
|
|
Mock -CommandName Start-Process -MockWith { Throw $mockStartProcessException }
|
|
|
|
It 'Should throw when Ensure set to Present and Start-Process fails' {
|
|
{ Set-TargetResource -Path $script:invalidPath `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Ensure 'Present'
|
|
} | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Start-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Wait-ProcessCount -Exactly 0 -Scope It
|
|
Assert-MockCalled -CommandName New-InvalidOperationException -Exactly 1 -Scope It
|
|
}
|
|
|
|
Mock -CommandName Wait-ProcessCount -MockWith { return $false }
|
|
Mock -CommandName Start-Process -MockWith {}
|
|
|
|
It 'Should throw when there is a failure waiting for the process to start' {
|
|
{ Set-TargetResource -Path $script:invalidPath `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Ensure 'Present'
|
|
} | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Start-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Wait-ProcessCount -Exactly 1 -Scope It
|
|
}
|
|
|
|
Mock -CommandName Wait-ProcessCount -MockWith { return $true }
|
|
|
|
It 'Should not throw when Ensure set to Present and processes are already running' {
|
|
{ Set-TargetResource -Path $script:validPath1 `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Ensure 'Present'
|
|
} | Should -Not -Throw
|
|
|
|
Assert-MockCalled -CommandName Expand-Path -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessCimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Start-Process -Exactly 0 -Scope It
|
|
Assert-MockCalled -CommandName Wait-ProcessCount -Exactly 0 -Scope It
|
|
}
|
|
}
|
|
|
|
Describe 'WindowsProcess\Test-TargetResource' {
|
|
Mock -CommandName Expand-Path -MockWith { return $Path }
|
|
Mock -CommandName Get-ProcessCimInstance -MockWith {
|
|
if ($Path -eq $script:validPath1)
|
|
{
|
|
return @($script:mockProcess1, $script:mockProcess3)
|
|
}
|
|
elseif ($Path -eq $script:validPath2)
|
|
{
|
|
return @($script:mockProcess2)
|
|
}
|
|
elseif ($Path -eq $script:validPath3)
|
|
{
|
|
return @($script:errorProcess)
|
|
}
|
|
else
|
|
{
|
|
return @()
|
|
}
|
|
}
|
|
|
|
It 'Should return true when Ensure set to Present and process is running' {
|
|
$testTargetResourceResult = Test-TargetResource -Path $script:validPath1 `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Ensure 'Present'
|
|
$testTargetResourceResult | Should -BeTrue
|
|
}
|
|
|
|
It 'Should return false when Ensure set to Present and process is not running' {
|
|
$testTargetResourceResult = Test-TargetResource -Path $script:invalidPath `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Ensure 'Present'
|
|
$testTargetResourceResult | Should -BeFalse
|
|
}
|
|
|
|
It 'Should return true when Ensure set to Absent and process is not running and Credential passed' {
|
|
$testTargetResourceResult = Test-TargetResource -Path $script:invalidPath `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Credential $script:testCredential `
|
|
-Ensure 'Absent'
|
|
$testTargetResourceResult | Should -BeTrue
|
|
}
|
|
|
|
It 'Should return false when Ensure set to Absent and process is running' {
|
|
$testTargetResourceResult = Test-TargetResource -Path $script:validPath1 `
|
|
-Arguments $script:mockProcess1.Arguments `
|
|
-Ensure 'Absent'
|
|
$testTargetResourceResult | Should -BeFalse
|
|
}
|
|
|
|
}
|
|
|
|
Describe 'WindowsProcess\Expand-Path' {
|
|
Mock -CommandName New-InvalidArgumentException -MockWith { Throw $script:exceptionMessage }
|
|
Mock -CommandName Test-Path -MockWith { return $true }
|
|
|
|
It 'Should return the original path when path is rooted' {
|
|
$rootedPath = 'C:\testProcess.exe'
|
|
|
|
$expandPathResult = Expand-Path -Path $rootedPath
|
|
$expandPathResult | Should -Be $rootedPath
|
|
}
|
|
|
|
Mock -CommandName Test-Path -MockWith { return $false }
|
|
|
|
It 'Should throw an invalid argument exception when Path is rooted and does not exist' {
|
|
$rootedPath = 'C:\invalidProcess.exe'
|
|
|
|
{ Expand-Path -Path $rootedPath} | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName New-InvalidArgumentException -Exactly 1 -Scope It
|
|
}
|
|
|
|
It 'Should throw an invalid argument exception when Path is unrooted and does not exist' {
|
|
$unrootedPath = 'invalidfile.txt'
|
|
|
|
{ Expand-Path -Path $unrootedPath} | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName New-InvalidArgumentException -Exactly 1 -Scope It
|
|
}
|
|
}
|
|
|
|
Describe 'WindowsProcess\Get-ProcessCimInstance' {
|
|
Mock -CommandName Get-Process -MockWith { return @($script:mockProcess2) }
|
|
Mock -CommandName Get-CimInstance -MockWith { return $script:mockProcess2 }
|
|
|
|
It 'Should return the correct process when it exists and no arguments passed' {
|
|
$resultProcess = Get-ProcessCimInstance -Path $script:mockProcess2.Path
|
|
$resultProcess | Should -Be @($script:mockProcess2)
|
|
|
|
Assert-MockCalled -CommandName Get-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-CimInstance -Exactly 1 -Scope It
|
|
}
|
|
|
|
Mock -CommandName Get-Process -MockWith { return @($script:mockProcess1) }
|
|
Mock -CommandName Get-CimInstance -MockWith { return $script:mockProcess1 }
|
|
|
|
It 'Should return the correct process when it exists and arguments are passed' {
|
|
$resultProcess = Get-ProcessCimInstance -Path $script:mockProcess1.Path `
|
|
-Arguments $script:mockProcess1.Arguments
|
|
$resultProcess | Should -Be @($script:mockProcess1)
|
|
|
|
Assert-MockCalled -CommandName Get-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-CimInstance -Exactly 1 -Scope It
|
|
}
|
|
|
|
$expectedProcesses = @($script:mockProcess1, $script:mockProcess1, $script:mockProcess1)
|
|
Mock -CommandName Get-Process -MockWith { return $expectedProcesses }
|
|
Mock -CommandName Get-CimInstance -MockWith { return $script:mockProcess1 }
|
|
|
|
It 'Should return the correct processes when multiple exist' {
|
|
$resultProcess = Get-ProcessCimInstance -Path $script:mockProcess1.Path `
|
|
-Arguments $script:mockProcess1.Arguments
|
|
|
|
Compare-Object -ReferenceObject $expectedProcesses -DifferenceObject $resultProcess | Should -Be $null
|
|
|
|
Assert-MockCalled -CommandName Get-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-CimInstance -Exactly 3 -Scope It
|
|
}
|
|
|
|
Mock -CommandName Get-Process -MockWith { return @($script:mockProcess2, $script:mockProcess2) }
|
|
Mock -CommandName Get-CimInstance -MockWith { return @($script:mockProcess2, $script:mockProcess2) }
|
|
|
|
It 'Should return the correct processes when they exists and cim instance threshold is lower than number of processes found' {
|
|
$resultProcess = Get-ProcessCimInstance -Path $script:mockProcess2.Path `
|
|
-Arguments $script:mockProcess2.Arguments `
|
|
-UseGetCimInstanceThreshold 1
|
|
$resultProcess | Should -Be @($script:mockProcess2, $script:mockProcess2)
|
|
|
|
Assert-MockCalled -CommandName Get-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-CimInstance -Exactly 1 -Scope It
|
|
}
|
|
|
|
Mock -CommandName Get-Process -MockWith { return @($script:mockProcess2) }
|
|
Mock -CommandName Get-CimInstance -MockWith { return $script:mockProcess2 }
|
|
Mock -CommandName Get-ProcessOwner -MockWith { return ($env:computerName + '\' + $script:testUsername) } `
|
|
-ParameterFilter { ($Process -eq $script:mockProcess2) }
|
|
|
|
It 'Should return the correct process when it exists and Credential is passed in' {
|
|
$resultProcess = Get-ProcessCimInstance -Path $script:mockProcess2.Path `
|
|
-Credential $script:testCredential
|
|
$resultProcess | Should -Be @($script:mockProcess2)
|
|
|
|
Assert-MockCalled -CommandName Get-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-CimInstance -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-ProcessOwner -Exactly 1 -Scope It
|
|
}
|
|
|
|
Mock -CommandName Get-Process -MockWith { return @($script:mockProcess3, $script:mockProcess3, $script:mockProcess4, $script:mockProcess2) }
|
|
Mock -CommandName Get-CimInstance -MockWith { return @($script:mockProcess3, $script:mockProcess3, $script:mockProcess4, $script:mockProcess2) }
|
|
Mock -CommandName Get-ProcessOwner -MockWith { return ($env:computerName + '\' + $script:testUsername) } `
|
|
-ParameterFilter { ($Process -eq $script:mockProcess3) }
|
|
Mock -CommandName Get-ProcessOwner -MockWith { return ('wrongDomain' + '\' + $script:testUsername) } `
|
|
-ParameterFilter { ($Process -eq $script:mockProcess4) -or ($Process -eq $script:mockProcess2) }
|
|
|
|
It 'Should return only processes that match Credential' {
|
|
$resultProcess = Get-ProcessCimInstance -Path $script:mockProcess3.Path `
|
|
-Credential $script:testCredential `
|
|
-Arguments $script:mockProcess3.Arguments `
|
|
-UseGetCimInstanceThreshold 1
|
|
$resultProcess | Should -Be @($script:mockProcess3, $script:mockProcess3)
|
|
|
|
Assert-MockCalled -CommandName Get-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-CimInstance -Exactly 1 -Scope It
|
|
}
|
|
|
|
Mock -CommandName Get-ProcessOwner -MockWith { return ($env:computerName + '\' + $script:testUsername) } `
|
|
-ParameterFilter { ($Process -eq $script:mockProcess3) -or ($Process -eq $script:mockProcess2) }
|
|
Mock -CommandName Get-ProcessOwner -MockWith { return ('wrongDomain' + '\' + $script:testUsername) } `
|
|
-ParameterFilter { ($Process -eq $script:mockProcess4) }
|
|
|
|
It 'Should return only processes that match Credential and Arguments' {
|
|
$resultProcess = Get-ProcessCimInstance -Path $script:mockProcess3.Path `
|
|
-Credential $script:testCredential `
|
|
-Arguments $script:mockProcess3.Arguments `
|
|
-UseGetCimInstanceThreshold 1
|
|
$resultProcess | Should -Be @($script:mockProcess3, $script:mockProcess3)
|
|
|
|
Assert-MockCalled -CommandName Get-Process -Exactly 1 -Scope It
|
|
Assert-MockCalled -CommandName Get-CimInstance -Exactly 1 -Scope It
|
|
}
|
|
}
|
|
|
|
Describe 'WindowsProcess\ConvertTo-EscapedStringForWqlFilter' {
|
|
It 'Should return the same string when there are no escaped characters' {
|
|
$inputString = 'testString%$.@123'
|
|
$convertedString = ConvertTo-EscapedStringForWqlFilter -FilterString $inputString
|
|
$convertedString | Should -Be $inputString
|
|
}
|
|
|
|
It 'Should return a string with escaped characters: ("\)' {
|
|
$inputString = '\test"string"\123'
|
|
$expectedString = '\\test\"string\"\\123'
|
|
$convertedString = ConvertTo-EscapedStringForWqlFilter -FilterString $inputString
|
|
$convertedString | Should -Be $expectedString
|
|
}
|
|
|
|
It "Should return a string with escaped characters: ('\)" {
|
|
$inputString = "\test'string'\123"
|
|
$expectedString = "\\test\'string\'\\123"
|
|
$convertedString = ConvertTo-EscapedStringForWqlFilter -FilterString $inputString
|
|
$convertedString | Should -Be $expectedString
|
|
}
|
|
}
|
|
|
|
Describe 'WindowsProcess\Get-ProcessOwner' {
|
|
$mockOwner = @{
|
|
Domain = 'Mock Domain'
|
|
User = 'Mock User'
|
|
}
|
|
Mock -CommandName Get-ProcessOwnerCimInstance -MockWith { return $mockOwner }
|
|
|
|
It 'Should return the correct string with domain\user' {
|
|
$owner = Get-ProcessOwner -Process $script:mockProcess1
|
|
$owner | Should -Be ($mockOwner.Domain + '\' + $mockOwner.User)
|
|
}
|
|
|
|
It 'Should return the correct string with default-domain\user when domain is not there' {
|
|
$mockOwner.Domain = $null
|
|
$owner = Get-ProcessOwner -Process $script:mockProcess1
|
|
$owner | Should -Be ($env:computerName + '\' + $mockOwner.User)
|
|
}
|
|
|
|
}
|
|
|
|
Describe 'WindowsProcess\Get-ArgumentsFromCommandLineInput' {
|
|
It 'Should return the correct arguments when single quotes are used' {
|
|
$inputString = 'test.txt a b c'
|
|
$argumentsReturned = Get-ArgumentsFromCommandLineInput -CommandLineInput $inputString
|
|
$argumentsReturned | Should -Be 'a b c'
|
|
}
|
|
|
|
It 'Should return the correct arguments when double quotes are used' {
|
|
$inputString = '"test file test" a b c'
|
|
$argumentsReturned = Get-ArgumentsFromCommandLineInput -CommandLineInput $inputString
|
|
$argumentsReturned | Should -Be 'a b c'
|
|
}
|
|
|
|
It 'Should return an empty string when an empty string is passed in' {
|
|
$inputString = $null
|
|
$resultString = [System.String]::Empty
|
|
$argumentsReturned = Get-ArgumentsFromCommandLineInput -CommandLineInput $inputString
|
|
$argumentsReturned | Should -Be $resultString
|
|
}
|
|
|
|
It 'Should return an empty string when there are no arguments' {
|
|
$inputString = 'test.txt'
|
|
$resultString = [System.String]::Empty
|
|
$argumentsReturned = Get-ArgumentsFromCommandLineInput -CommandLineInput $inputString
|
|
$argumentsReturned | Should -Be $resultString
|
|
}
|
|
}
|
|
|
|
Describe 'WindowsProcess\Assert-HashtableDoesNotContainKey' {
|
|
$mockHashtable = @{
|
|
Key1 = 'test key1'
|
|
Key2 = 'test key2'
|
|
Key3 = 'test key3'
|
|
}
|
|
Mock -CommandName New-InvalidArgumentException -MockWith { Throw $script:exceptionMessage }
|
|
|
|
It 'Should not throw an exception if the hashtable does not contain a key' {
|
|
$mockKey = @('k1', 'k2', 'k3', 'k4', 'k5')
|
|
{ Assert-HashTableDoesNotContainKey -Hashtable $mockHashtable -Key $mockKey } | Should -Not -Throw
|
|
}
|
|
|
|
It 'Should throw an exception if the hashtable contains a key' {
|
|
$mockKey = @('k1', 'k2', 'Key3', 'k4', 'k5')
|
|
{ Assert-HashTableDoesNotContainKey -Hashtable $mockHashtable -Key $mockKey } | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName New-InvalidArgumentException -Exactly 1 -Scope It
|
|
}
|
|
}
|
|
|
|
Describe 'WindowsProcess\Wait-ProcessCount' {
|
|
$mockProcessSettings = @{
|
|
Path = 'mockPath'
|
|
Arguments = 'mockArguments'
|
|
}
|
|
Mock -CommandName Get-ProcessCimInstance -MockWith { return @($script:mockProcess1, $script:mockProcess3) }
|
|
|
|
It 'Should return true when all processes are returned' {
|
|
$processCountResult = Wait-ProcessCount -ProcessSettings $mockProcessSettings -ProcessCount 2
|
|
$processCountResult | Should -BeTrue
|
|
}
|
|
|
|
It 'Should return false when not all processes are returned' {
|
|
$processCountResult = Wait-ProcessCount -ProcessSettings $mockProcessSettings `
|
|
-ProcessCount 3 `
|
|
-WaitTime 10
|
|
$processCountResult | Should -BeFalse
|
|
}
|
|
}
|
|
|
|
Describe 'WindowsProcess\Assert-PathArgumentRooted' {
|
|
Mock -CommandName New-InvalidArgumentException -MockWith { Throw $script:exceptionMessage }
|
|
|
|
It 'Should not throw when path is rooted' {
|
|
$rootedPath = 'C:\testProcess.exe'
|
|
|
|
{ Assert-PathArgumentRooted -PathArgumentName 'mock test name' `
|
|
-PathArgument $rootedPath } | Should -Not -Throw
|
|
}
|
|
|
|
It 'Should throw an invalid argument exception when Path is unrooted' {
|
|
$unrootedPath = 'invalidfile.txt'
|
|
|
|
|
|
{ Assert-PathArgumentRooted -PathArgumentName 'mock test name' `
|
|
-PathArgument $unrootedPath } | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName New-InvalidArgumentException -Exactly 1 -Scope It
|
|
}
|
|
}
|
|
|
|
Describe 'WindowsProcess\Assert-PathArgumentValid' {
|
|
Mock -CommandName New-InvalidArgumentException -MockWith { Throw $script:exceptionMessage }
|
|
|
|
It 'Should not throw when path is valid' {
|
|
Mock -CommandName Test-Path -MockWith { return $true }
|
|
|
|
{ Assert-PathArgumentValid -PathArgumentName 'test name' `
|
|
-PathArgument 'validPath' } | Should -Not -Throw
|
|
}
|
|
|
|
It 'Should throw an invalid argument exception when Path is not valid' {
|
|
Mock -CommandName Test-Path -MockWith { return $false }
|
|
|
|
{ Assert-PathArgumentValid -PathArgumentName 'test name' `
|
|
-PathArgument 'invalidPath' } | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName New-InvalidArgumentException -Exactly 1 -Scope It
|
|
}
|
|
}
|
|
|
|
Describe 'WindowsProcess\Split-Credential' {
|
|
Mock -CommandName New-InvalidArgumentException -MockWith { Throw $script:exceptionMessage }
|
|
|
|
It 'Should return correct domain and username with @ seperator' {
|
|
$testUsername = 'user@domain'
|
|
$testPassword = ConvertTo-SecureString -String 'dummy' -AsPlainText -Force
|
|
$testCredential = New-Object -TypeName 'PSCredential' -ArgumentList @($testUsername, $testPassword)
|
|
|
|
$splitCredentialResult = Split-Credential -Credential $testCredential
|
|
|
|
$splitCredentialResult.Domain | Should -Be 'domain'
|
|
$splitCredentialResult.Username | Should -Be 'user'
|
|
}
|
|
|
|
It 'Should return correct domain and username with \ seperator' {
|
|
$testUsername = 'domain\user'
|
|
$testPassword = ConvertTo-SecureString -String 'dummy' -AsPlainText -Force
|
|
$testCredential = New-Object -TypeName 'PSCredential' -ArgumentList @($testUsername, $testPassword)
|
|
|
|
$splitCredentialResult = Split-Credential -Credential $testCredential
|
|
|
|
$splitCredentialResult.Domain | Should -Be 'domain'
|
|
$splitCredentialResult.Username | Should -Be 'user'
|
|
}
|
|
|
|
It 'Should return correct domain and username with a local user' {
|
|
$testUsername = 'localuser'
|
|
$testPassword = ConvertTo-SecureString -String 'dummy' -AsPlainText -Force
|
|
$testCredential = New-Object -TypeName 'PSCredential' -ArgumentList @($testUsername, $testPassword)
|
|
|
|
$splitCredentialResult = Split-Credential -Credential $testCredential
|
|
|
|
$splitCredentialResult.Domain | Should -Be $env:computerName
|
|
$splitCredentialResult.Username | Should -Be 'localuser'
|
|
}
|
|
|
|
It 'Should throw an invalid argument exception when more than one \ in username' {
|
|
$testUsername = 'user\domain\foo'
|
|
$testPassword = ConvertTo-SecureString -String 'dummy' -AsPlainText -Force
|
|
$testCredential = New-Object -TypeName 'PSCredential' -ArgumentList @($testUsername, $testPassword)
|
|
|
|
{ $null = Split-Credential -Credential $testCredential } | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName New-InvalidArgumentException -Exactly 1 -Scope It
|
|
}
|
|
|
|
It 'Should throw an invalid argument exception when more than one @ in username' {
|
|
$testUsername = 'user@domain@foo'
|
|
$testPassword = ConvertTo-SecureString -String 'dummy' -AsPlainText -Force
|
|
$testCredential = New-Object -TypeName 'PSCredential' -ArgumentList @($testUsername, $testPassword)
|
|
|
|
{ $null = Split-Credential -Credential $testCredential } | Should -Throw -ExpectedMessage $script:exceptionMessage
|
|
|
|
Assert-MockCalled -CommandName New-InvalidArgumentException -Exactly 1 -Scope It
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Exit-DscResourceTestEnvironment -TestEnvironment $script:testEnvironment
|
|
}
|