2017-01-10 36 views
0

私はOffice365ライセンストラッキングに使用しています。実際にはそれは良いように見えますが、プロセスを完了するのには時間がかかります。ほとんどの時間がGet-MsolUserによって費やされます(ユーザー1を処理している間にユーザー2のデータを取得しているなど)... BTWには約3000人以上のクラウドユーザーがいます。スクリプトの速度?大規模なユーザーのPowerShell処理が非常に遅い - より良い方法がありますか?

$T1 = @() 
$O365Users = Get-MsolUser -All 
ForEach ($O365User in $O365Users) 
{ 
    $ADuser = Get-ADUser -Filter { UserPrincipalName -eq $O365User.UserPrincipalName } -Properties whenCreated, Enabled, lastlogondate 
    $O365Stats = Get-MailboxStatistics $O365User.DisplayName -ErrorAction SilentlyContinue 
    $O365Smtp = Get-Recipient $O365User.DisplayName -ErrorAction SilentlyContinue 
    If ($O365Stats -and $O365Smtp) { 
    If (($ADUser.Enabled -eq $true) -and ($O365User.isLicensed -eq $true)) 
    { 
     $T1 += New-Object psobject -Property @{ 
      CollectDate = $(Get-Date); 
      ADUserUPN = $($ADUser.UserPrincipalName); 
      O365UserUPN = $($O365User.UserPrincipalName); 
      ADUserCreated = $($ADUser.whenCreated); 
      ADUserEnabled = $($ADUser.Enabled); 
      ADLastLogonDate = $($ADUser.LastLogonDate); 
      O365Licensed = $($O365User.isLicensed); 
      O365LastLogonTime = $($O365Stats.LastLogonTime); 
      O365SMTPAddress = $($O365Smtp.PrimarySMTPAddress) 
     } 
    } 
} 
} 
$T1 = $T1 | Sort-Object -Property ADUserCreated 
$T1 | Format-Table 
$T1 | Export-Csv -Path $OutputFile -NoTypeInformation 
Write-Host "Output to $OutputFile" 
+0

あなたが言ったように、それを平行にしてください – 4c74356b41

+0

あなたのように感謝の男は私のスクリプトを再構築できますか?明確にしてください – Arbelac

答えて

0

Powershellで並列処理を設定します。

PS Workflowsをご利用いただきありがとうございます。

私たちは-parallelを持っていますので、これは並列呼び出しで役立ちます。

それとは別に、我々はを呼び出し、パラレル

のための1つの機能を持っている。これは、それのためのリンクは次のとおりです。Invoke-Parallel Function

注:例としては、関数自体の内部で言及されています。一度コンパイルしてもその関数でget-helpを使うことができます。

+0

ありがとう人私のスクリプトをInvoke-Parallel関数と組み合わせるにはどうすればいいですか?私は正しいですか? Invoke-Parallel -scriptfile myscript.ps1 -runspaceTimeout 10 -throttle 10 – Arbelac

+0

@Arbelac:はい、あなたの仕事をする必要があります... –

0

、パイプラインを使用して早い段階でフィルタリングし、すでにかなり物事をスピードアップする必要があり、アレイに追加する回避:また

Get-MsolUser -All | Where-Object { 
    $_.IsLicensed 
} | ForEach-Object { 
    $upn = $_.UserPrincipalName 
    Get-ADUser -Filter "UserPrincipalName -eq '$upn'" -Properties whenCreated, Enabled, lastlogondate 
} | Where-Object { 
    $_.Enabled 
} | ForEach-Object { 
    $O365Stats = Get-MailboxStatistics $_.DisplayName -ErrorAction SilentlyContinue 
    $O365Smtp = Get-Recipient $_.DisplayName -ErrorAction SilentlyContinue 
    if ($O365Stats -and $O365Smtp) { 
     New-Object -Type PSObject -Property @{ 
      'CollectDate'  = Get-Date 
      'ADUserUPN'   = $_.UserPrincipalName 
      'O365UserUPN'  = $_.UserPrincipalName 
      'ADUserCreated'  = $_.whenCreated 
      'ADUserEnabled'  = $_.Enabled 
      'ADLastLogonDate' = $_.LastLogonDate 
      'O365Licensed'  = $true 
      'O365LastLogonTime' = $O365Stats.LastLogonTime 
      'O365SMTPAddress' = $O365Smtp.PrimarySMTPAddress 
     } 
    } 
} | Sort-Object -Property ADUserCreated | Export-Csv -Path $OutputFile -NoType 

、なぜ一体部分式を持つように夢中誰もがありますか?必要な場所で使用してください。それらが不要なときにあなたのコードを難読化しないでください。

+0

をチェックしてください。 – Arbelac

+0

次のような警告が表示されます。デフォルトでは、最初の1000個のアイテムだけが返されます。 ResultSizeパラメーターを使用して、返される項目の数を指定します。すべての項目を返すには、 "-ResultSize Unlimited"を指定します。実際にアイテムの数に応じて、すべてのアイテムを返すには長い時間がかかり、大量のメモリを消費する可能性があるので、 です。また、結果を変数に格納することはお勧めしません。 では、結果を別のタスクまたはスクリプトにパイプして、バッチ変更を実行します。何をお勧めしますか? – Arbelac

+0

正確にあなたはその警告を受け取りますか? AFAICS 'Get-MsolUser'を除くすべてのコマンドレットは個々のアイテムを返すべきですが、ドキュメントによると' Get-MsolUser'のパラメータは '-ResultSize'ではなく-MaxResults(デフォルトは500)です。 –

関連する問題