0

I have a script that deals with Active Directory User objects (Microsoft.ActiveDirectory.Management.ADUser). I explicitly list the type in the function that processes these objects:

function Write-ADUser {
    param (
        [Microsoft.ActiveDirectory.Management.ADUser]$user
    )
(...)

I also want this function to be able to take objects from remote sessions. The challenge is that objects returned from remote sessions are of the deserialized variety:

C:\> icm -session $sess { get-aduser -identity testuser -credential $cred } | gm

   TypeName: Deserialized.Microsoft.ActiveDirectory.Management.ADUser

Is there a way to have my function param block accept either the "live" object or the deserialized variant? My function doesn't need to use methods - the deserialized variant has (or can be made to have) what I need.

James S.
  • 475
  • 3
  • 10

1 Answers1

1

The parameter sets idea was interesting and a helpful lead. After reviewing the documentation, this is the best option I could come up with:

function Write-ADUser {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [ValidateScript({
            if ($_.GetType().Name -notin @('ADUser', 'PSObject')) {
                throw ("Error:  Invalid type ````{0}'' - expecting ADUser.") -f $_.GetType().Name
            } else {
                $true
            }
         })]
        $user
    )

    ...

One other comment. When looking into parameter sets I kept getting an error about ADUser. However, upon further digging I believe that error is because the Microsoft Active Directory PowerShell module isn't installed on my test computer. Therefore, the 'ADUser' type isn't defined. Because I want this script to run on computers that don't necessarily have the ADModule I am using the above logic. However, if I could guarantee that ADModule was present then I think parameter sets would be the way to go.

Apologies for not providing clearer requirements. I'm still learning PowerShell...

Note - updated based on feedback from @zett42

James S.
  • 475
  • 3
  • 10
  • 1
    I would use a [`ValidateScript`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_advanced_parameters?view=powershell-7.1#validatescript-validation-attribute) attribute to do this. – zett42 Mar 19 '21 at 18:36
  • @zett42 That's a cool idea. I tried it and it works. However, I kept the above because the diagnostic message from ValidateScript is pretty cryptic. – James S. Mar 19 '21 at 19:13
  • 1
    That's true. Therefore instead of returning `$false` in case of invalid argument, I throw an exception, which will be shown in the diagnostic message: `ValidateScript({ if(argument is valid){ $true } else { throw "argument is invalid blah..." }}) ` – zett42 Mar 19 '21 at 19:46
  • @zett42 Nice! I like it. I adopted that instead. – James S. Mar 19 '21 at 20:06