Pester Testing .NET with Copilot Part 3
I've been sharing my experiences writing Pester tests for a PowerShell function that uses the .NET Framework instead of invoking native cmdlets. The process has also involved using GitHub Copilot in VS Code. As you've seen this has been hit and miss. While there were times when Copilot accelerated my scripting, there were times, I needed to step in.
When we left off, I had refactored the function to use private functions that wrapped around the .NET method invocations. You can only Pester test or mock a PowerShell command like a function or cmdlet.
This is where the function stands now after the refactoring.
Function Get-OSDetail {
<#
.Synopsis
Get operating system details via CIM
.Description
Use this command to query one or more remote computers using CIM to get operating
system details.
.Example
PS C:\> Get-OSDetail
Name : Microsoft Windows 11 Pro
Version : 10.0.22635
Build : 22635
OSArchitecture : 64-bit
RegisteredUser : Jeff
RegisteredOrganization :
InstallDate : 5/17/2022 2:54:52 PM
ComputerName : THINKX1-JH
.Link
Get-CimInstance
#>
[CmdletBinding()]
[OutputType('OSDetail')]
Param(
[Parameter(
Position = 0,
ValueFromPipeline
)]
[Alias('CN', 'Server')]
[ValidateNotNullOrEmpty()]
[Microsoft.Management.Infrastructure.CimSession[]]$CimSession = $Env:ComputerName
)
Begin {
Write-Verbose "Starting $($MyInvocation.MyCommand)"
#define the WQL query
$Query = 'Select CSName,Caption,Version,BuildNumber,InstallDate,OSArchitecture,RegisteredUser,Organization from Win32_OperatingSystem'
#initialize reference variables
New-Variable -Name ci
New-Variable -Name ce
#define private helper functions that I can mock in my pester tests
function TestCimConnection {
param(
[Microsoft.Management.Infrastructure.CimSession]$CimSession
)
$cs.TestConnection([ref]$ci, [ref]$ce)
} #TestCimConnection
function InvokeQuery {
param(
[Microsoft.Management.Infrastructure.CimSession]$CimSession,
[string]$Query
)
$CimSession.QueryInstances('Root/Cimv2', 'WQL', $Query)
}
} #begin
Process {
foreach ($cs in $CimSession) {
#capture connection failures to a variable
Write-Verbose "Testing connection to $($cs.ComputerName.ToUpper())"
If (TestCimConnection -CimSession $cs) {
Write-Verbose "Querying $($cs.ComputerName.ToUpper())"
$data = InvokeQuery -CimSession $cs -Query $Query
[PSCustomObject]@{
PSTypeName = 'OSDetail'
Name = $data.Caption
Version = $data.Version -as [Version]
Build = $data.BuildNumber -as [Int32]
OSArchitecture = $data.OSArchitecture
RegisteredUser = $data.RegisteredUser
RegisteredOrganization = $data.Organization
InstallDate = $data.InstallDate
ComputerName = $data.CSName
}
}
else {
Write-Warning "Unable to connect to $($cs.ComputerName.ToUpper()). $($ce.Message)"
}
} #foreach
} #process
End {
Write-Verbose "Ending $($MyInvocation.MyCommand)"
} #end
} #end function Get-OSDetail
Want to read the full issue?