Reputation: 187
I am running a PowerShell script that gets some information from a csv file, stores it in an object array and then does some action depending on what's on the file. It actually only does one thing:
If one column has a AD group it copies the row for every member of that group.
The thing is I am really new at scripting and at the beginning the files were small, so everything went ok. Now I have huge files and the script is taking hours to execute.
$file = "c:\Report.csv"
$fileContent = Import-csv $file | select *, UserName
foreach($item in $fileContent)
{
$LoginName = $item.LoginName
$LoginNameClean = $LoginName.split("\")
$LoginNameClean = $LoginNameClean[1].trimstart("_")
$ObjectClass = (Get-ADObject -filter {SamAccountName -eq $LoginNameClean}).ObjectClass
$UserName = $null
if($ObjectClass -eq "user")
{
$UserName = Get-ADUser -identity $LoginNameClean -properties DisplayName
if($UserName)
{
$item.UserName = $UserName.DisplayName
}
}
elseif($ObjectClass -eq "group")
{
$GroupUsers = Get-ADGroupMember -identity $LoginNameClean -Recursive
foreach($user in $GroupUsers)
{
$UserInsideGroup = Get-ADUser -identity $user -properties DisplayName
$UserInsideGroupName = $UserInsideGroup.DisplayName
$newRow = New-Object PsObject -Property @{"URL" = $item.URL; "SiteListFolderItem" = $item.SiteListFolderItem; "TitleName" = $item.TitleName; "PermissionType" = $item.PermissionType; "LoginName" = $item.LoginName; "Permissions" = $Item.Permissions; "UserName" = $UserInsideGroup.DisplayName;}
$fileContent += $newRow
}
}
}
$fileContent | Export-Csv -NoTypeInformation -Path "c:\ReportUpgraded.csv"
Any tips on how to improve the performance of this is much appreciated
Thanks in advance.
edit: I am using PS 2.0
As commentaries suggested, I am trying to replace the fileContent += newRow.
I am trying to use add member but it's giving me this error:
Add-Member : Cannot add a member with the name "URL" because a member with that name already exists. If you wan t to overwrite the member anyway, use the Force parameter to overwrite it. At line:1 char:26 + $fileContent | Add-Member <<<< -MemberType NoteProperty -Name "URL"-Value "teste" + CategoryInfo : InvalidOperation: (@{SiteListFolde...me=; URL=teste}:PSObject) [Add-Member], Inv
alidOperationException + FullyQualifiedErrorId : MemberAlreadyExists,Microsoft.PowerShell.Commands.AddMemberCommand
How I can I use this properly? Add-member is not adding but replacing members
Upvotes: 1
Views: 2088
Reputation: 187
I manage to reduce 30 times the execution time with a couple of things.
First, I switched array to a array list so that I could use theArray.Add() method. Then, in order to stop making requests to the AD all the time, I am saving the information in excel sheets with the name of the group, so that it will only request AD once per group.
Here is the script:
$file = "ReportBefore.csv"
$fileContent = Import-csv $file | select *, UserName
[System.Collections.ArrayList]$ArrayList = $fileContent
foreach($item in $fileContent)
{
$LoginName = $item.LoginName
$LoginNameClean = $LoginName.split("\")
$LoginNameClean = $LoginNameClean[1].trimstart("_")
$ObjectClass = (Get-ADObject -filter {SamAccountName -eq $LoginNameClean}).ObjectClass
$UserName = $null
if($ObjectClass -eq "user")
{
$UserName = Get-ADUser -identity $LoginNameClean -properties DisplayName
if($UserName)
{
$item.UserName = $UserName.DisplayName
}
}
elseif($ObjectClass -eq "group")
{
$exportString = "\\folder\username$\Desktop\ADGroups\" + $LoginNameClean + ".csv"
if([System.IO.File]::Exists($exportString))
{
$GroupUsers = Import-csv $exportString | select *
}
else
{
$GroupUsers = Get-ADGroupMember -identity $LoginNameClean -Recursive | Select samAccountName,Name, @{Name="DisplayName";Expression={(Get-ADUser $_.distinguishedName -Properties Displayname).Displayname}}
$GroupUsers | Export-Csv -NoTypeInformation -Path $exportString
}
foreach($user in $GroupUsers)
{
$UserInsideGroupName = $user.DisplayName
$newRow = New-Object PsObject -Property @{"URL" = $item.URL; "SiteListFolderItem" = $item.SiteListFolderItem; "TitleName" = $item.TitleName; "PermissionType" = $item.PermissionType; "LoginName" = $item.LoginName; "Permissions" = $Item.Permissions; "UserName" = $UserInsideGroupName;}
#$filecontent += $newRow
$ArrayList.Add($newRow)
}
}
}
$ArrayList | Export-Csv -NoTypeInformation -Path "\ReportAfter.csv"
Upvotes: 2