如果有比我写的更好的方法,我会先解释我想要实现的目标。我正在尝试获取一个用户列表(但在下面的示例中,我只是查询一个用户来测试脚本),他们将Exchange计划设置为禁用。
我需要应用的过滤器位于licenses.servicestatus对象上。如果您运行并输出此对象,则获取:
ServicePlan ProvisioningStatus
----------- ------------------
INTUNE_O365 PendingActivation
YAMMER_ENTERPRISE PendingInput
RMS_S_ENTERPRISE Success
OFFICESUBSCRIPTION Success
MCOSTANDARD Disabled
SHAREPOINTWAC Disabled
SHAREPOINTENTERPRISE Disabled
EXCHANGE_S_ENTERPRISE Success
我需要的是如果查询在provisioningstatus列中找到“disabled”并且在serviceplan列中找到匹配的“exchange”通配符,则返回true。
我的下面的脚本没有这样做,相反,如果它发现已禁用并以任何顺序进行交换,则返回true,只要禁用和交换在表中的任何位置,IE将始终返回true,而不是它们在一个位置匹配的位置行。这和我想要的一样接近。
Get-MsolUser -UserPrincipalName "exampleuser@dom.com"| ? {"disabled" -in $_.licenses.servicestatus.provisioningstatus -and ($_.licenses.servicestatus| Out-String| ? {$_ -like "*exchange*"})}
我可以看到我出错的地方,我只是不知道如何解决它。该脚本有效地运行两个单独的搜索,而不是将它们组合在一起。
另请注意我使用out-string的原因是因为上表没有将serviceplan作为字符串输出。
如果有更好的方法可以做到这一点,那么请指教,否则我只需要知道如何匹配同一行中数组中的两个条件。
答案 0 :(得分:1)
Get-MsolUser -UserPrincipalName "exampleuser@dom.com" |
ForEach-Object {
if( ($_.licenses.serviceplan.tostring() -match 'Exchange') -and ($_.licenses.ProvisioningStatus -eq 'Disabled') )
{
$true
}
Else
{
$false
}
}
检查你的代码:
"disabled" -in $_.licenses.servicestatus.provisioningstatus
因为
而无法工作 $_.licenses
是一个包含2个属性Servicestatus
& Provisioningstatus
因此您可以$_.licenses.servicestatus
或$_.licenses.provisioningstatus
使用$_.licenses.servicestatus.provisioningstatus
或module MyUtils
def self.build_collection_full_email(collection)
I18n.t('app_name') + " <" + self.build_collection_email(collection) + ">"
end
end
,而不是sender_name = MyUtils.build_collection_full_email(@collection)
,因为没有这样的属性。
此外,-in用于检查数组中是否包含不适合您正在执行的操作的值。
答案 1 :(得分:0)
你的问题让我考虑使用我在@JaredPar撰写的文章中读到的Test-Any。基本思想是评估对象数组中的任何项是否具有一组匹配条件。
我把它放到这样的模块中。
function Test-Any {
[CmdletBinding()]
param([scriptblock]$EvaluateCondition,
[Parameter(ValueFromPipeline = $true)] $ObjectToTest)
begin {
$any = $false
}
process {
if (-not $any -and (& $EvaluateCondition $ObjectToTest)) {
$any = $true
}
}
end {
$any
}
}
function Test-All {
[CmdletBinding()]
param([scriptblock]$EvaluateCondition,
[Parameter(ValueFromPipeline = $true)] $ObjectToTest)
begin {
$all = $true
}
process {
if ($all -and ((& $EvaluateCondition $ObjectToTest) -eq $false)) {
$all = $false
}
}
end {
$all
}
}
Export-ModuleMember -Function Test-Any, Test-All
现在您可能已经注意到还有一个Test-All功能。这不用于此示例,但可能会派上用场。
现在你可以像这样解决你的任务。
注意我已经用一些适当的测试数据替换了对Get-msoluser的调用。
Import-Module AllAny
$testdata = @(
(new-object psobject -Property @{ServicePlan="ExchangePlan";licenses = new-object psobject -Property @{ProvisioningStatus="Disabled"}}),
(new-object psobject -Property @{ServicePlan="SomeOtherPlan";licenses = new-object psobject -Property @{ProvisioningStatus="Enabled"}}))
$userProp = $testdata #Get-MsolUser -UserPrincipalName "exampleuser@dom.com"
if ($userProp | Test-Any {$Args.serviceplan -match "Exchange" -and $Args.licenses.ProvisioningStatus -eq 'Disabled'})
{
echo "Do your thing!"
}
希望它有意义。
答案 2 :(得分:0)
我自己解决了这个问题:
Get-MsolUser -UserPrincipalName "exampleuser@dom.com" | ? {$_.licenses.servicestatus| Out-String | ? {$_ -like "*exchange*disabled*"}}
答案 3 :(得分:0)
这是相当古老的,但是鉴于Azure查询的局限性,这是我想出的一个稍微整洁的解决方案。
首先,创建一个至少包含您需要匹配的条件的用户列表
$users = Get-Msoluser -EnabledFilter EnabledOnly |
Where { ($_.licenses.serviceplan.tostring() -match 'Exchange') `
-and ($_.licenses.ProvisioningStatus -eq 'Disabled') }
您得到的是在其Licenses属性内某处同时具有“ Exchange”和“ Disabled”的用户,但它们可能不在同一行。
如果您正在寻找“未经许可”的用户,请小心,因为可以重新分配许可。在这里,我使用Get-AzureADUser
和AssignedPlans属性。此用户已获得SfB的两次许可,但仍然有效。
AssignedTimestamp CapabilityStatus Service ServicePlanId
----------------- ---------------- ------- -------------
2019-12-05 03:46:34 Enabled MicrosoftCommunicationsOnline 3e26ee1f-8a5f-4d52-aee2-b81ce45c8f40
2019-09-26 07:16:48 Deleted MicrosoftCommunicationsOnline 4828c8ec-dc2e-4779-b502-87ac9ce28ab7
在执行第一遍以填充$users
列表之后,要使用户至少拥有一个具有Exchange&Disabled值的行,请在每个用户的Licenses属性上均使用Where
语句检查属性。以下内容将UPN转储到$licensedUsers
中,以便以后导出。
$licensedUsers = @()
$users | Foreach {
$u = $_
if ($u.licenses | where { ($_.serviceplan.tostring() -match 'Exchange') `
-and ($_.ProvisioningStatus -eq 'Disabled') }) {
$licensedUsers += $u.userPrincipalName
#if you want more properties in the report, create a PSCustomObject here instead
}
}
如果您只想让根本没有任何有效的Exchange许可证的用户使用,则希望颠倒逻辑以查找未启用所有许可证的帐户。< / p>
if (-not ($u.licenses | where { ($_.serviceplan.tostring() -match 'Exchange') `
-and ($_.ProvisioningStatus -eq 'Enabled')) })
答案 4 :(得分:0)
在同一行中有两件事可以做到这一点(据我所知):
因此,我认为这应该在单个命令中满足原始海报的要求:
Get-MsolUser -UserPrincipalName "exampleuser@dom.com" | Where-Object { $_.Licenses.ServiceStatus | Where-Object { $_.ServicePlan.ServiceName -like "*exchange*" -and $_.ProvisioningStatus -eq "Disabled" } }
或更短的命令:
Get-MsolUser -UserPrincipalName "exampleuser@dom.com" | ? { $_.Licenses.ServiceStatus | ? { $_.ServicePlan.ServiceName -like "*exchange*" -and $_.ProvisioningStatus -eq "Disabled" } }