Powershell 脚本开关参数
Powershell Script Switch parameters
我正在尝试创建一个脚本,使用对象 ID 和应用程序 ID(用于应用程序和服务主体)定位用户、组、应用程序或服务主体。我希望脚本能够 运行 带或不带开关参数。我希望它能够搜索全部或特定搜索位置。例如:
搜索全部:./test.ps1 -ObjectId "xxxx-xxxx-xxxx-xxxxxx"
仅限用户和组:./test.ps1 -ObjectId "xxxx-xxxx-xxxx-xxxxxx" -User -Group
仅限应用程序:./test.ps1 -ObjectId "xxxx-xxxx-xxxx-xxxxxx" -App
如果有人能检查我的工作并提供反馈and/or建议,将不胜感激!谢谢!
[CmdletBinding(DefaultParameterSetName='SearchAll')]
param(
[Parameter(Mandatory=$true)]
[ValidatePattern("^[a-z_0-9]{8}[-][a-z_0-9]{4}[-][a-z_0-9]{4}[-][a-z_0-9]{4}[-][a-z_0-9]{12}")]
$objectID,
[Parameter(ParameterSetName = 'Switches')]
[switch]$User,
[Parameter(ParameterSetName = 'Switches')]
[switch]$Group,
[Parameter(ParameterSetName = 'Switches')]
[switch]$sp,
[Parameter(ParameterSetName = 'Switches')]
[switch]$App
)
if($PSCmdlet.ParameterSetName -eq 'Switches')
{
if ($user.IsPresent) {
Get-AzADUser -ObjectId $objectID | Select-Object Mail, DisplayName
$found = $true }
if ($group.IsPresent) {
Get-AzADGroup -ObjectId $objectID | Select-Object DisplayName, Description, Id
$found = $true }
if ($app.IsPresent) {
Get-AzADApplication -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
Get-AzADApplication -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
$found = $true }
if ($sp.IsPresent) {
Get-AzADServicePrincipal -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
Get-AzADServicePrincipal -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
$found = $true }
if (-not $found) { Write-Warning "Not found." }
}
else{
$user = Get-AzADUser -ObjectId $objectID
if ($user)
{
$user | Format-List Mail, DisplayName
}
else
{
$group = Get-AzADGroup -ObjectId $objectID
if ($group)
{
$group | Format-List DisplayName, Description, Id
}
else
{
$appO = Get-AzADApplication -ObjectId $objectID
if ($appO)
{
Write-Host "ObjectID"
$appO | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
}
else
{
$appA = Get-AzADApplication -ApplicationId $objectID
if ($appA)
{
Write-Host "Application ID"
$appA | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
}
else
{
$spO = Get-AzADServicePrincipal -ObjectId $objectID
if ($spO)
{
$spO | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
}
else
{
$spA = Get-AzADServicePrincipal -ApplicationId $objectID
if ($spA)
{
$spA | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
}
else
{
Write-Warning "Object does not exist."
}
}
}
}
}
}
}
此外,
if (-not $found) { Write-Warning "Not found." }
行似乎不起作用。有什么建议吗?
看起来你正在将 $found
设置为 $true 而不管结果
Get-AzADUser
或任何其他命令。由于您在每个 if/else 脚本块中都这样做,因此像 -not $found
这样的表达式将始终返回 false,因此永远不会写入警告。
简单的解决方案是将 returned/found 对象分配给一个变量,然后测试该变量是否已填充以设置 $found
。然后像以前一样继续输出变量:
if ( $user ) {
$AzADUser = Get-AzADUser -ObjectId $objectID
If( $AzADUser ) { $found = $true }
$AzADUser | Select-Object Mail, DisplayName
}
if ( $group ) {
$AzADGroup = Get-AzADGroup -ObjectId $objectID
If( $AzADGroup ) { $found = $true }
$AzADGroup | Select-Object DisplayName, Description, Id
}
if ( $app ) {
$AzADApplication = @(Get-AzADApplication -ObjectId $objectID)
$AzADApplication += Get-AzADApplication -ApplicationId $objectID
If( $AzADApplication ) { $found = $true }
$AzADApplication| Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
}
if ( $sp ) {
$AzADServicePrincipal = @(Get-AzADServicePrincipal -ObjectId $objectID)
$AzADServicePrincipal += Get-AzADServicePrincipal -ApplicationId $objectID
If( $AzADServicePrincipal ) { $found = $true }
$AzADServicePrincipal | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
}
if (-not $found) { Write-Warning "Not found." }
注意:您不需要引用.IsPresent
显然您可以对不同的开关参数重复此操作。
但是,这有点冗长,因为您使用同一个变量来表示可能返回的几种不同类型的对象。此外,您将根据对象类型返回不同的属性。
您可以使用 Switch 语句改进它:
Switch ([Boolean]$true) {
$user {
Get-AzADUser -ObjectId $objectID | Select-Object Mail, DisplayName
}
$group {
Get-AzADGroup -ObjectId $objectID | Select-Object DisplayName, Description, Id
}
$app {
Get-AzADApplication -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
Get-AzADApplication -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
}
$sp {
Get-AzADServicePrincipal -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
Get-AzADServicePrincipal -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
}
Default {
Write-Warning "Not found."
}
}
一个优点是任何匹配的脚本块都会执行,但默认情况除外,如果没有其他块执行,默认情况下只会执行 运行。在这种情况下,您不需要重复的 If
语句或 $found
.
即使使用 Switch
的更清晰的版本,代码仍然相当重复。我认为有一种更通用的方法来查询您最初可能不知道的对象类型。如果这是一个本地 AD 实现,我会使用 Get-ADObject
,然后根据它的对象类型 returns 输出不同的内容。这将完全消除对开关参数的需要。也许您可以使用 Azure Active Directory PowerShell module 中的 Get-AzureADObjectById
来采用类似的策略
我正在尝试创建一个脚本,使用对象 ID 和应用程序 ID(用于应用程序和服务主体)定位用户、组、应用程序或服务主体。我希望脚本能够 运行 带或不带开关参数。我希望它能够搜索全部或特定搜索位置。例如:
搜索全部:./test.ps1 -ObjectId "xxxx-xxxx-xxxx-xxxxxx"
仅限用户和组:./test.ps1 -ObjectId "xxxx-xxxx-xxxx-xxxxxx" -User -Group
仅限应用程序:./test.ps1 -ObjectId "xxxx-xxxx-xxxx-xxxxxx" -App
如果有人能检查我的工作并提供反馈and/or建议,将不胜感激!谢谢!
[CmdletBinding(DefaultParameterSetName='SearchAll')]
param(
[Parameter(Mandatory=$true)]
[ValidatePattern("^[a-z_0-9]{8}[-][a-z_0-9]{4}[-][a-z_0-9]{4}[-][a-z_0-9]{4}[-][a-z_0-9]{12}")]
$objectID,
[Parameter(ParameterSetName = 'Switches')]
[switch]$User,
[Parameter(ParameterSetName = 'Switches')]
[switch]$Group,
[Parameter(ParameterSetName = 'Switches')]
[switch]$sp,
[Parameter(ParameterSetName = 'Switches')]
[switch]$App
)
if($PSCmdlet.ParameterSetName -eq 'Switches')
{
if ($user.IsPresent) {
Get-AzADUser -ObjectId $objectID | Select-Object Mail, DisplayName
$found = $true }
if ($group.IsPresent) {
Get-AzADGroup -ObjectId $objectID | Select-Object DisplayName, Description, Id
$found = $true }
if ($app.IsPresent) {
Get-AzADApplication -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
Get-AzADApplication -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
$found = $true }
if ($sp.IsPresent) {
Get-AzADServicePrincipal -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
Get-AzADServicePrincipal -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
$found = $true }
if (-not $found) { Write-Warning "Not found." }
}
else{
$user = Get-AzADUser -ObjectId $objectID
if ($user)
{
$user | Format-List Mail, DisplayName
}
else
{
$group = Get-AzADGroup -ObjectId $objectID
if ($group)
{
$group | Format-List DisplayName, Description, Id
}
else
{
$appO = Get-AzADApplication -ObjectId $objectID
if ($appO)
{
Write-Host "ObjectID"
$appO | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
}
else
{
$appA = Get-AzADApplication -ApplicationId $objectID
if ($appA)
{
Write-Host "Application ID"
$appA | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
}
else
{
$spO = Get-AzADServicePrincipal -ObjectId $objectID
if ($spO)
{
$spO | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
}
else
{
$spA = Get-AzADServicePrincipal -ApplicationId $objectID
if ($spA)
{
$spA | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
}
else
{
Write-Warning "Object does not exist."
}
}
}
}
}
}
}
此外,
if (-not $found) { Write-Warning "Not found." }
行似乎不起作用。有什么建议吗?
看起来你正在将 $found
设置为 $true 而不管结果
Get-AzADUser
或任何其他命令。由于您在每个 if/else 脚本块中都这样做,因此像 -not $found
这样的表达式将始终返回 false,因此永远不会写入警告。
简单的解决方案是将 returned/found 对象分配给一个变量,然后测试该变量是否已填充以设置 $found
。然后像以前一样继续输出变量:
if ( $user ) {
$AzADUser = Get-AzADUser -ObjectId $objectID
If( $AzADUser ) { $found = $true }
$AzADUser | Select-Object Mail, DisplayName
}
if ( $group ) {
$AzADGroup = Get-AzADGroup -ObjectId $objectID
If( $AzADGroup ) { $found = $true }
$AzADGroup | Select-Object DisplayName, Description, Id
}
if ( $app ) {
$AzADApplication = @(Get-AzADApplication -ObjectId $objectID)
$AzADApplication += Get-AzADApplication -ApplicationId $objectID
If( $AzADApplication ) { $found = $true }
$AzADApplication| Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
}
if ( $sp ) {
$AzADServicePrincipal = @(Get-AzADServicePrincipal -ObjectId $objectID)
$AzADServicePrincipal += Get-AzADServicePrincipal -ApplicationId $objectID
If( $AzADServicePrincipal ) { $found = $true }
$AzADServicePrincipal | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
}
if (-not $found) { Write-Warning "Not found." }
注意:您不需要引用.IsPresent
显然您可以对不同的开关参数重复此操作。
但是,这有点冗长,因为您使用同一个变量来表示可能返回的几种不同类型的对象。此外,您将根据对象类型返回不同的属性。
您可以使用 Switch 语句改进它:
Switch ([Boolean]$true) {
$user {
Get-AzADUser -ObjectId $objectID | Select-Object Mail, DisplayName
}
$group {
Get-AzADGroup -ObjectId $objectID | Select-Object DisplayName, Description, Id
}
$app {
Get-AzADApplication -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
Get-AzADApplication -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
}
$sp {
Get-AzADServicePrincipal -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
Get-AzADServicePrincipal -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
}
Default {
Write-Warning "Not found."
}
}
一个优点是任何匹配的脚本块都会执行,但默认情况除外,如果没有其他块执行,默认情况下只会执行 运行。在这种情况下,您不需要重复的 If
语句或 $found
.
即使使用 Switch
的更清晰的版本,代码仍然相当重复。我认为有一种更通用的方法来查询您最初可能不知道的对象类型。如果这是一个本地 AD 实现,我会使用 Get-ADObject
,然后根据它的对象类型 returns 输出不同的内容。这将完全消除对开关参数的需要。也许您可以使用 Azure Active Directory PowerShell module 中的 Get-AzureADObjectById
来采用类似的策略