Pester模拟带/不带ParameterFilter的Get-ADUser报错求助
Hey there! Let's work through this Pester mocking issue with your Active Directory script— I’ve helped a few folks troubleshoot similar problems with older Pester versions, so let’s break this down.
First, that "Cannot validate argument on parameter 'Identity'" error usually pops up because:
- The AD module’s cmdlets do strict parameter validation, even when mocked. In Pester 4.1.1, you need to make sure your mocks properly match the parameter sets being used, and return objects that fit the expected ADUser structure.
- Your mock might not be targeting the exact parameter combination your script is using, leading the underlying AD cmdlet validation to kick in.
Let’s start with concrete examples based on your simplified scripts. First, let’s assume your Dummy.ps1 has functions like this:
# Dummy.ps1 function Get-ADUsersFromOU { param( [string]$OU ) Get-ADUser -Filter * -SearchBase $OU -Properties * } function Get-ADUsersInGroup { param( [string]$Group ) $groupMembers = Get-ADGroupMember -Identity $Group | Where-Object ObjectClass -eq 'user' Get-ADUser -Identity $groupMembers.SamAccountName -Properties * }
Now, here’s how to write the Dummy.Tests.ps1 with proper mocks for both scenarios, tailored to Pester 4.1.1:
Step 1: Prepare Mock AD User Data
First, create mock objects that match the structure of real ADUser objects— this avoids validation issues later:
# Dummy.Tests.ps1 $mockADUsers = @( [PSCustomObject]@{ SamAccountName = 'user1' Name = 'User One' DistinguishedName = 'CN=User One,OU=Test,DC=contoso,DC=com' ObjectClass = 'user' }, [PSCustomObject]@{ SamAccountName = 'user2' Name = 'User Two' DistinguishedName = 'CN=User Two,OU=Test,DC=contoso,DC=com' ObjectClass = 'user' } )
Step 2: Mock Get-ADUser for OU Queries
Use -ParameterFilter to target the exact parameter combination your script uses (Filter = * and SearchBase = your OU). This ensures the mock only triggers when that specific call happens:
Describe "AD User Retrieval from OU" { Context "When querying a specific OU" { Mock Get-ADUser { return $mockADUsers } -ParameterFilter { $Filter -eq '*' -and $SearchBase -eq 'OU=Test,DC=contoso,DC=com' } It "Returns all users in the target OU" { $result = Get-ADUsersFromOU -OU 'OU=Test,DC=contoso,DC=com' $result.Count | Should Be 2 $result.SamAccountName | Should Contain 'user1' Assert-MockCalled Get-ADUser -Exactly 1 -Scope It } } }
Step 3: Mock Get-ADGroupMember + Get-ADUser for Group Queries
For the group member scenario, you need two mocks: one for Get-ADGroupMember to return the group’s user, and one for Get-ADUser to fetch that specific user. Again, use -ParameterFilter to avoid mismatched calls:
Describe "AD User Retrieval from Group" { Context "When querying members of a specific group" { # Mock Get-ADGroupMember to return a single user member Mock Get-ADGroupMember { return [PSCustomObject]@{ SamAccountName = 'user1' ObjectClass = 'user' } } -ParameterFilter { $Identity -eq 'TestGroup' } # Mock Get-ADUser to return our mock user when Identity is 'user1' Mock Get-ADUser { return $mockADUsers | Where-Object SamAccountName -eq $Identity } -ParameterFilter { $Identity -eq 'user1' } It "Returns the user in the target group" { $result = Get-ADUsersInGroup -Group 'TestGroup' $result.SamAccountName | Should Be 'user1' Assert-MockCalled Get-ADGroupMember -Exactly 1 -Scope It Assert-MockCalled Get-ADUser -Exactly 1 -Scope It } } }
Key Fixes for the Identity Error
- Precise Parameter Matching: Using
-ParameterFilterensures your mock only responds to the exact parameter inputs your script uses, preventing the AD cmdlet’s validation from firing on unexpected calls. - Valid Mock Objects: Returning objects with properties like
SamAccountNameandObjectClassmatches what the AD module expects, so downstream validation doesn’t fail. - Handle Array Inputs: If your script passes multiple identities to
Get-ADUser, adjust the mock’s-ParameterFilterto handle arrays (e.g.,$Identity -contains 'user1') and return the corresponding mock users.
A few extra tips for Pester 4.1.1:
- Use
-Verifiableon mocks if you want to ensure they’re called (add-Verifiableto the Mock command, then runAssert-VerifiableMocksat the end of your test). - If you still hit validation issues, try adding
-ModuleName ActiveDirectoryto your Mock command— this tells Pester to mock the cmdlet directly from the AD module, which can help bypass some validation.
内容的提问来源于stack exchange,提问作者DarkLite1

