Powershell 中的 Foreach 嵌套循环问题

Foreach Nested loops issue in powershell

我需要做的是使用 $userID 中匹配的员工 ID(如果存在)将与 $O365Users 中每个用户名关联的许可属性与启用属性进行比较。使用标准嵌套 ForEach(上图)我们使用此脚本来帮助管理我们的本地 Active Directory 和 MSOL(Microsoft Online – Office 365)对象。我的问题是:我有一个与 foreach 循环相关的问题,所以同一个对象 returns 多个(永远)我想为每个用户逐行执行

Import-Module ActiveDirectory
Import-Module MSOnline

$password = ConvertTo-SecureString 'PASSWORD' -AsPlainText -Force
$LiveCred = New-Object System.Management.Automation.PSCredential ("username@domain.com", $password)
New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection

Connect-MsolService -Credential $Livecred

$O365Users = Get-MsolUser -All
ForEach ($O365User in $O365Users)
{
  $userID = Import-CSV "c:\Export\list.csv"
  $ADuser = Get-ADUser -Filter "EmployeeID -eq $($userID.EmployeeID)" -Properties whenCreated, Enabled, SAMAccountName
  If (($ADUser.Enabled -eq $True) -and ($O365User.isLicensed = $true))
    {

     Get-MsolUSer -UserPrincipalName $ADuser.UserPrincipalName
        Set-MsolUserLicense -UserPrincipalName $ADuser.UserPrincipalName -RemoveLicenses "company:ENTERPRISEPACK"
    }
}

CSV 文件:

EmployeeID
52576
1234
8599

给你,这应该有效

$userID = Import-Csv "c:\export\list.csv"

foreach ($user in $userID){

    $ADuser = Get-ADUser -Filter "EmployeeId -eq $($user.EmployeeID)" -Properties whenCreated, Enabled, SAMAccountName
    $O365User = Get-MsolUser -UserPrincipalName $ADuser.UserPrincipalName

    if(($ADuser.Enabled -eq $true) -and ($O365User.isLicensed -eq $true)){
        Get-MsolUSer -UserPrincipalName $ADuser.UserPrincipalName
        Set-MsolUserLicense -UserPrincipalName $ADuser.UserPrincipalName -RemoveLicenses "company:ENTERPRISEPACK"
    }

}

关于性能的后续问题(我认为可能会提高性能,没有保证也没有测试):

$userID = Import-Csv "c:\export\list.csv"
$adusers = Get-ADUser -Filter * -properties EmployeeID,whenCreated,Enabled,SAMAccountname
$msolusers = Get-MsolUser -All

foreach ($user in $userID){

$ADuser = $adusers | where {$_.EmployeeID -eq $user.EmployeeID}
$O365User = $msolusers | where {$_.UserPrincipalName -eq $ADuser.UserPrincipalName}

if(($ADuser.Enabled -eq $true) -and ($O365User.isLicensed -eq $true)){
    Set-MsolUserLicense -UserPrincipalName $ADuser.UserPrincipalName -RemoveLicenses "company:ENTERPRISEPACK"
}

}

取决于有多少 AD / MSOL 用户,你必须匹配这可能会减少或增加执行时间,你将不得不测试,因为我不能。 我还删除了 if 语句中的 get-msoluser,因为它的唯一功能是生成(不必要的?)输出。如果我的 "improvements" 有任何问题,请告诉我,我们看看能做些什么 ;)

请尝试:

Import-Module ActiveDirectory
Import-Module MSOnline

$password = ConvertTo-SecureString 'PASSWORD' -AsPlainText -Force
$LiveCred = New-Object System.Management.Automation.PSCredential ("username@domain.com", $password)
New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection

Connect-MsolService -Credential $Livecred


$userIDs = Import-CSV "c:\Export\list.csv"
$O365Users = Get-MsolUser -All

ForEach ($O365User in $O365Users)
{
  foreach ($userID in $userIDs) 
    {
    $ADuser = Get-ADUser -Filter "EmployeeID -eq $($userID.EmployeeID)" -Properties whenCreated, Enabled, SAMAccountName,ObjectGUID
    $valuetoconvert=$ADuser.ObjectGUID
    $guid = [GUID]$valuetoconvert
    $bytearray = $guid.tobytearray()
    $ImmutableID = [system.convert]::ToBase64String($bytearray)


  If (($ADUser.Enabled -eq $True) -and ($O365User.isLicensed = $true) -and ($ImmutableID -eq $O365User.ImmutableID ) )
    {
        Get-MsolUSer -UserPrincipalName $ADuser.UserPrincipalName
        Set-MsolUserLicense -UserPrincipalName $ADuser.UserPrincipalName -RemoveLicenses "company:ENTERPRISEPACK"
    }

    }   
}