Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a variable as a switch parameter in Powershell

I'm trying to create a powershell script that will grab all Active Directory accounts that are enabled, and inactive for 90 days. The script will prompt the user to choose between querying computer or user accounts. Depending on the choice, it will pass it over to the main command as a variable.

The commands work correctly if I don't pass a variable.

I'm not sure if what I'm trying to do is possible.

Sorry for any bad code formatting. Just starting out.

Clear-Host
write-host "`nProgram searches for Enabled AD users account that have not logged in for more than 90 days. `nIt searches the entire domain and saves the results to a CSV file on users desktop." "`n"

$choice = Read-host -Prompt " What do you want to search for Computer or Users Accounts`nType 1 for users`nType 2 for Computers`n`nChoice"

$account
if ($choice -eq 1) {
    $account = UsersOnly
}
Elseif ($choice -eq 2) {
    $account = ComputersOnly
}
Else {
    write-host "This is not an option `n exiting program"
    exit
}

$FileName = Read-Host -Prompt "What do you want to name the CSV file"
$folderPath = "$env:USERPROFILE\Desktop\$FileName.csv"

Search-ADAccount -AccountInactive -TimeSpan 90 -$account | Where-Object { $_.Enabled -eq $true } | select Name, UserPrincipalName, DistinguishedName | Export-Csv -Path $folderPath
like image 846
Michael Fisher Avatar asked Feb 02 '19 01:02

Michael Fisher


People also ask

How do I create a switch parameter in PowerShell?

To create a switch parameter in a function, specify the switch type in the parameter definition. Switch parameters are easy to use and are preferred over Boolean parameters, which have a less natural syntax for PowerShell. For example, to use a switch parameter, the user types the parameter in the command.

How do you pass a variable in PowerShell?

You can pass variables to functions by reference or by value. When you pass a variable by value, you are passing a copy of the data. In the following example, the function changes the value of the variable passed to it. In PowerShell, integers are value types so they are passed by value.

How do you declare a parameter in PowerShell?

Defining parameters Parameters can be created for scripts and functions and are always enclosed in a param block defined with the param keyword, followed by opening and closing parentheses.


1 Answers

Splatting is the way to achieve this. It's so named because you reference a variable with @ instead of $ and @ kind of looks a "splat".

it works by creating a hashtable, which is a type of dictionary (key/value pairs). In PowerShell we create hashtable literals with @{}.

To use splatting you just make a hashtable where each key/value pair is a parameter name and value, respectively.

So for example if you wanted to call Get-ChildItem -LiteralPath $env:windir -Filter *.exe you could also do it this way:

$params = @{
    LiteralPath = $env:windir
    Filter = '*.exe'
}

Get-ChildItem @params

You can also mix and match direct parameters with splatting:

$params = @{
    LiteralPath = $env:windir
    Filter = '*.exe'
}

Get-ChildItem @params -Verbose

This is most useful when you need to conditionally omit a parameter, so you can turn this:

if ($executablesOnly) {
    Get-ChildItem -LiteralPath $env:windir -Filter *.exe
} else {
    Get-ChildItem -LiteralPath $env:windir
}

Into this:

$params = @{
    LiteralPath = $env:windir
}

if ($executablesOnly) {
   $params.Filter = '*.exe'
}

Get-ChildItem @params

or this:

$params = @{}

if ($executablesOnly) {
   $params.Filter = '*.exe'
}

Get-ChildItem -LiteralPath $env:windir @params

With only 2 possible choices, the if/else doesn't look that bad, but as your choices multiply and become more complicated, it gets to be a nightmare.


Your situation: there's one thing I want to note first. The parameters you're trying to alternate against are switch parameters. That means when you supply them you usually only supply the name of the parameter. In truth, these take boolean values that default to true when the name is supplied. You can in fact override them, so you could do Search-ADAccount -UsersOnly:$false but that's atypical.

Anyway the point of mentioning that is that it may have been confusing how you would set its value in a hashtable for splatting purposes, but the simple answer is just give them a boolean value (and usually it's $true).

So just changing your code simply:

$account = if ($choice -eq 1) {
    @{ UsersOnly = $true }
} elseif ($choice -eq 2) {
    @{ ComputersOnly = $true }
}

# skipping some stuff

Search-ADAccount -AccountInactive -TimeSpan 90 @account

I also put the $account assignment on the left side of the if instead of inside, but that's your choice.

like image 53
briantist Avatar answered Oct 11 '22 13:10

briantist