Created
July 4, 2024 07:07
-
-
Save davidlu1001/9081a503f8c16e838d108e0be669f31f to your computer and use it in GitHub Desktop.
Testing RemoteOps.ps1 with Pester
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# RemoteOps.Tests.ps1 | |
BeforeAll { | |
. $PSScriptRoot\RemoteOps.ps1 | |
Mock Write-Log {} | |
Mock Resolve-FullPath { $Path } | |
Mock Get-Content { "Write-Output 'Test Script'" } | |
} | |
Describe "RemoteOps - Command Execution" { | |
BeforeEach { | |
Mock Invoke-Command { | |
[PSCustomObject]@{ | |
PSComputerName = $ComputerName | |
Status = "Success" | |
Output = "Command executed successfully" | |
} | |
} | |
} | |
It "Executes a command on a single remote host" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1" -Command "Get-Process" | |
$result.ComputerName | Should -Be "Server1" | |
$result.Status | Should -Be "Success" | |
} | |
It "Executes a command on multiple remote hosts" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1","Server2" -Command "Get-Service" | |
$result.Count | Should -Be 2 | |
$result[0].ComputerName | Should -Be "Server1" | |
$result[1].ComputerName | Should -Be "Server2" | |
} | |
It "Handles command execution timeout" { | |
Mock Invoke-Command { Start-Sleep -Seconds 10 } | |
{ .\RemoteOps.ps1 -ComputerName "SlowServer" -Command "Get-Process" -Timeout 5 } | Should -Throw "Operation timed out after 5 seconds" | |
} | |
It "Respects ThrottleLimit parameter" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1","Server2","Server3" -Command "Get-Process" -ThrottleLimit 2 | |
$result.Count | Should -Be 3 | |
Should -Invoke Invoke-Command -Times 1 -ParameterFilter { $ThrottleLimit -eq 2 } | |
} | |
} | |
Describe "RemoteOps - Script Execution" { | |
BeforeEach { | |
Mock Invoke-Command { | |
[PSCustomObject]@{ | |
PSComputerName = $ComputerName | |
Status = "Success" | |
Output = "Script executed successfully" | |
} | |
} | |
Mock Test-Path { $true } | |
} | |
It "Executes a script on a remote host" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1" -ScriptPath "C:\Scripts\Test.ps1" | |
$result.ComputerName | Should -Be "Server1" | |
$result.Status | Should -Be "Success" | |
} | |
It "Executes a script with arguments" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1" -ScriptPath "C:\Scripts\Test.ps1" -ArgumentList @{Param1 = "Value1"; Param2 = "Value2"} | |
$result.ComputerName | Should -Be "Server1" | |
$result.Status | Should -Be "Success" | |
Should -Invoke Invoke-Command -Times 1 -ParameterFilter { $ArgumentList[0].ArgumentList.Param1 -eq "Value1" } | |
} | |
It "Handles non-existent script file" { | |
Mock Test-Path { $false } | |
{ .\RemoteOps.ps1 -ComputerName "Server1" -ScriptPath "C:\NonExistent.ps1" } | Should -Throw "Script file not found" | |
} | |
It "Handles relative script paths" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1" -ScriptPath ".\Test.ps1" | |
$result.Status | Should -Be "Success" | |
Should -Invoke Resolve-FullPath -Times 1 -ParameterFilter { $Path -eq ".\Test.ps1" } | |
} | |
} | |
Describe "RemoteOps - Copy Operations" { | |
BeforeEach { | |
Mock Invoke-Command { | |
[PSCustomObject]@{ | |
PSComputerName = $ComputerName | |
Status = "Success" | |
Output = "File/Directory copied successfully" | |
} | |
} | |
Mock Test-Path { $true } | |
} | |
It "Copies a single file to a remote host" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1" -Source "C:\LocalFile.txt" -Destination "C:\RemoteFolder" | |
$result.ComputerName | Should -Be "Server1" | |
$result.Status | Should -Be "Success" | |
} | |
It "Copies multiple files to a remote host" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1" -Source "C:\File1.txt","C:\File2.txt" -Destination "C:\RemoteFolder" | |
$result.ComputerName | Should -Be "Server1" | |
$result.Status | Should -Be "Success" | |
Should -Invoke Invoke-Command -Times 1 -ParameterFilter { $ArgumentList[0].Source.Count -eq 2 } | |
} | |
It "Copies a directory to a remote host" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1" -Source "C:\LocalFolder" -Destination "C:\RemoteFolder" | |
$result.ComputerName | Should -Be "Server1" | |
$result.Status | Should -Be "Success" | |
} | |
It "Handles non-existent source path" { | |
Mock Test-Path { $false } | |
{ .\RemoteOps.ps1 -ComputerName "Server1" -Source "C:\NonExistent" -Destination "C:\Remote" } | Should -Throw "Cannot find path" | |
} | |
It "Handles relative source paths" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1" -Source ".\LocalFile.txt" -Destination "C:\RemoteFolder" | |
$result.Status | Should -Be "Success" | |
Should -Invoke Resolve-FullPath -Times 1 -ParameterFilter { $Path -eq ".\LocalFile.txt" } | |
} | |
} | |
Describe "RemoteOps - Config File Handling" { | |
BeforeEach { | |
Mock Invoke-Command { | |
[PSCustomObject]@{ | |
PSComputerName = $ComputerName | |
Status = "Success" | |
Output = "Operation completed" | |
} | |
} | |
Mock Test-Path { $true } | |
Mock Get-Content { @("Server1", "Server2", "Server3") } | |
} | |
It "Uses computers from config file" { | |
$result = .\RemoteOps.ps1 -ConfigFile "C:\servers.txt" -Command "Get-Process" | |
$result.Count | Should -Be 3 | |
$result[0].ComputerName | Should -Be "Server1" | |
$result[1].ComputerName | Should -Be "Server2" | |
$result[2].ComputerName | Should -Be "Server3" | |
} | |
It "Handles non-existent config file" { | |
Mock Test-Path { $false } | |
{ .\RemoteOps.ps1 -ConfigFile "C:\NonExistent.txt" -Command "Get-Process" } | Should -Throw "Config file not found" | |
} | |
It "Handles empty config file" { | |
Mock Get-Content { @() } | |
{ .\RemoteOps.ps1 -ConfigFile "C:\EmptyConfig.txt" -Command "Get-Process" } | Should -Throw "No valid hosts found in config file" | |
} | |
It "Handles relative config file path" { | |
$result = .\RemoteOps.ps1 -ConfigFile ".\servers.txt" -Command "Get-Process" | |
$result.Count | Should -Be 3 | |
Should -Invoke Resolve-FullPath -Times 1 -ParameterFilter { $Path -eq ".\servers.txt" } | |
} | |
} | |
Describe "RemoteOps - Error Handling and Edge Cases" { | |
BeforeEach { | |
Mock Invoke-Command { throw "Remote execution failed" } | |
} | |
It "Handles remote execution errors" { | |
$result = .\RemoteOps.ps1 -ComputerName "FailServer" -Command "Get-Process" | |
$result.Status | Should -Be "Error" | |
$result.Output | Should -BeLike "*Remote execution failed*" | |
} | |
It "Handles invalid parameter combinations" { | |
{ .\RemoteOps.ps1 -ComputerName "Server1" } | Should -Throw "Parameter set cannot be resolved" | |
} | |
It "Handles invalid ThrottleLimit" { | |
{ .\RemoteOps.ps1 -ComputerName "Server1" -Command "Get-Process" -ThrottleLimit 0 } | Should -Throw "Cannot validate argument on parameter 'ThrottleLimit'" | |
} | |
It "Handles invalid Timeout" { | |
{ .\RemoteOps.ps1 -ComputerName "Server1" -Command "Get-Process" -Timeout 0 } | Should -Throw "Cannot validate argument on parameter 'Timeout'" | |
} | |
It "Handles missing ComputerName and ConfigFile" { | |
{ .\RemoteOps.ps1 -Command "Get-Process" } | Should -Throw "No remote hosts specified" | |
} | |
} | |
Describe "RemoteOps - DryRun Functionality" { | |
It "Displays expected operations without executing them" { | |
$output = .\RemoteOps.ps1 -ComputerName "Server1" -Command "Get-Process" -DryRun | |
$output | Should -BeLike "*would execute command: Get-Process*" | |
} | |
It "Displays copy operations in dry run mode" { | |
$output = .\RemoteOps.ps1 -ComputerName "Server1" -Source "C:\LocalFile.txt" -Destination "C:\RemoteFolder" -DryRun | |
$output | Should -BeLike "*Would copy files/directories from C:\LocalFile.txt to C:\RemoteFolder on Server1*" | |
} | |
} | |
Describe "RemoteOps - Output File Handling" { | |
BeforeEach { | |
Mock Invoke-Command { | |
[PSCustomObject]@{ | |
PSComputerName = $ComputerName | |
Status = "Success" | |
Output = "Operation completed" | |
} | |
} | |
Mock Export-Csv {} | |
} | |
It "Exports results to CSV file" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1" -Command "Get-Process" -OutputFile "results.csv" | |
Should -Invoke Export-Csv -Times 1 -ParameterFilter { $Path -eq "results.csv" } | |
} | |
It "Handles relative output file path" { | |
$result = .\RemoteOps.ps1 -ComputerName "Server1" -Command "Get-Process" -OutputFile ".\results.csv" | |
Should -Invoke Resolve-FullPath -Times 1 -ParameterFilter { $Path -eq ".\results.csv" } | |
} | |
} | |
Describe "RemoteOps - Parallel Execution" { | |
It "Executes operations in parallel" { | |
Mock Invoke-Command { | |
Start-Sleep -Milliseconds 100 | |
[PSCustomObject]@{ | |
PSComputerName = $ComputerName | |
Status = "Success" | |
Output = "Operation completed" | |
} | |
} | |
$start = Get-Date | |
$result = .\RemoteOps.ps1 -ComputerName "Server1","Server2","Server3" -Command "Get-Process" -ThrottleLimit 3 | |
$end = Get-Date | |
$duration = ($end - $start).TotalMilliseconds | |
$duration | Should -BeLessThan 300 | |
$result.Count | Should -Be 3 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment