Search code examples
powershellparametersactive-directorypowershell-5.0

Variable Type Issue For Parameter? - Powershell


I am trying to run the below code to search for inactive user accounts in an OU. It seems like the type of variable I'm using may not be able to used with parameters. Does that seem correct and if so what type of variable should I be using?

$scope = "-UsersOnly" 

$accounts = Search-ADAccount -SearchBase "OU=Users,OU=testLab02,DC=test,DC=local" -AccountInactive -TimeSpan ([timespan]7D) $scope
    foreach($account in $accounts){
        If ($noDisable -notcontains $account.Name) {
            Write-Host $account
            #Disable-ADAccount -Identity $account.DistinguishedName -Verbose $whatIf | Export-Csv $logFile
        }
    }

I receive the below error:

enter image description here

Search-ADAccount : A positional parameter cannot be found that accepts argument '-UsersOnly'. At C:\Users\Administrator\Documents\Disable-ADAccounts.ps1:63 char:21 + ... $accounts = Search-ADAccount -SearchBase $OU.DistinguishedName -Accou ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Search-ADAccount], ParameterBindingException + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.ActiveDirectory.Management.Commands.SearchADAccount

However, if I run the command manually without variables it works as expected:

Search-ADAccount -SearchBase "OU=Users,OU=testLab02,DC=test,DC=local" -AccountInactive -TimeSpan ([timespan]7D) -UsersOnly

enter image description here


Solution

  • $scope = "-UsersOnly"

    You can't pass a (switch) parameter stored in a variable that way - it'll invariably be treated as a (positional) argument, which explains the error you saw; with directly passed arguments, only unquoted, literal tokens such as -UsersOnly are recognized as parameter names.

    You can use splatting to pass parameters via variables, which in your case means:

    # Define a hash table of parameter values.
    # This hash table encodes switch parameter -UsersOnly
    $scope = @{ UsersOnly = $true } # [switch] parameters are represented as Booleans
    
    # Note the use of sigil @ instead of $ to achieve splatting
    Search-ADAccount @scope -SearchBase "OU=Users,OU=testLab02,DC=test,DC=local" -AccountInactive -TimeSpan ([timespan]7D) 
    
    • $scope is defined as a hash table (@{ ... }) whose entries represent parameter name-value pairs.

      • Here, only one parameter name-value pair is defined:
        • Parameter name -UsersOnly (the entry key must be defined without the - sigil) ...
        • ... with value $true, which for a [switch] (flag) parameter is equivalent to passing the parameter; $false is typically[1] equivalent to omitting it.
    • To pass the parameter values represented by hashtable $scope to a command via splatting, sigil @ instead of $ must be used, i.e, @scope in this case.


    [1] A command can technically distinguish between a switch being omitted and it being passed with value $false, and on occasion that results in different behavior, notably with the common -Confirm parameter, where -Confirm:$false overrides the $ConfirmPreference preference variable.