在Powershell中将变量作为开关参数传递

Mic*_*her 5 powershell active-directory

我正在尝试创建一个Powershell脚本,该脚本将捕获所有已启用且在90天内处于非活动状态的Active Directory帐户。该脚本将提示用户在查询计算机或用户帐户之间进行选择。根据选择,它将作为变量传递给主命令。

如果我不传递变量,这些命令将正常工作。

我不确定我要做什么。

对不起,任何错误的代码格式。刚开始。

    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
Run Code Online (Sandbox Code Playgroud)

bri*_*ist 5

喷溅是实现此目的的方法。之所以这样命名,是因为您使用@而不是引用了一个变量,$并且@看起来有点像“ splat”。

它通过创建一个哈希表来工作,哈希表是一种字典(键/值对)。在PowerShell中,我们使用创建哈希表文字@{}

要使用splatting,您只需创建一个哈希表,其中每个键/值对分别是参数名称和值。

因此,例如,如果您想打电话,Get-ChildItem -LiteralPath $env:windir -Filter *.exe您也可以这样进行:

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

Get-ChildItem @params
Run Code Online (Sandbox Code Playgroud)

您还可以使用splatting混合和匹配直接参数:

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

Get-ChildItem @params -Verbose
Run Code Online (Sandbox Code Playgroud)

当您需要有条件地省略参数时,这是最有用的,因此可以将其设置为:

if ($executablesOnly) {
    Get-ChildItem -LiteralPath $env:windir -Filter *.exe
} else {
    Get-ChildItem -LiteralPath $env:windir
}
Run Code Online (Sandbox Code Playgroud)

变成这个:

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

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

Get-ChildItem @params
Run Code Online (Sandbox Code Playgroud)

或这个:

$params = @{}

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

Get-ChildItem -LiteralPath $env:windir @params
Run Code Online (Sandbox Code Playgroud)

只有两个可能的选择,if/ else看起来并不那么糟糕,但是随着选择的增加和变得越来越复杂,它就变成了一场噩梦。


您的情况:首先要注意一件事。您要替代的参数是开关参数。这意味着当您提供它们时,通常仅提供参数名称。实际上,这些名称采用的布尔值在提供名称时默认为true。实际上,您可以覆盖它们,因此可以这样做,Search-ADAccount -UsersOnly:$false但这是非典型的。

无论如何,提到的重点是它可能会混淆您如何出于散布目的而在哈希表中设置其值,但是简单的答案只是给他们一个布尔值(通常是$true)。

因此,只需简单地更改代码即可:

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

# skipping some stuff

Search-ADAccount -AccountInactive -TimeSpan 90 @account
Run Code Online (Sandbox Code Playgroud)

我还将$account作业放在if而不是内部的左侧,但这是您的选择。