I am just starting using powershell and I wonder why my parallel srcipt is more slower than my normal foreach object script?
My script for my normal foreachobject:
function Get-ADUsers { #get all users in nested groups }
function Get-NestedGroupUsers {
param (
[Parameter(Mandatory = $true)][String]$FileName,
[Parameter(Mandatory = $true)][String]$searchFileURL
)
$storageHolder = @()
# $storageHolder | Export-Csv -Path "C:\Users\demandx\Desktop\AD User Lists\$FileName.csv" -NoTypeInformation -Force
$groupList = Get-Content $searchFileURL
$groupList | ForEach-Object {
$allusers = Get-ADUsers -GroupName $_
$storageHolder += $allusers
}
$storageHolder | select ParentGroup, Name, EmployeeNumber, Enabled, LastLogonDate, PasswordLastSet |Export-Csv -Path "C:\Users\demandx\Desktop\$FileName.csv" -NoTypeInformation -Force
}
My script for foreach -parallel (I store the function inside psm1 then import here.)
Function Get-Members {
param (
[Parameter(Mandatory = $true)][String]$FileName,
[Parameter(Mandatory = $true)][String]$searchFileURL
)
$groupList = Get-Content $searchFileURL
$storageHolder = $groupList | ForEach-Object -Parallel {
Import-Module -Name "C:\Users\demandx\Desktop\Get-ADUserMembers.psm1"
Get-ADUserMembers -GroupName $_ | Select-Object ParentGroup, Name, EmployeeNumber, Enabled, LastLogonDate, PasswordLastSet
} -ThrottleLimit 5
$storageHolder | Export-Csv -Path "C:\Users\demandx\Desktop\AD User Lists\$FileName.csv" -NoTypeInformation -Force
}
The script or my get-adusers (get all the users in nested groups)
function Get-ADUsers {
param (
[Parameter(ValuefromPipeline = $true, mandatory = $true)][String] $GroupName
)
[int]$circular = $null
# result holder
$resultHolder = @()
$table = $null
$nestedmembers = $null
$adgroupname = $null
function Get-ADUsers {
param (
[Parameter(ValuefromPipeline = $true, mandatory = $true)][String] $GroupName
)
[int]$circular = $null
# result holder
$resultHolder = @()
$table = $null
$nestedmembers = $null
$adgroupname = $null
# get members of the group and member of
$ADGroupname = get-adgroup $groupname -properties memberof, members
# list all members as list (no headers) and save to var
$memberof = $adgroupname | select -expand memberof
if ($adgroupname) {
if ($circular) {
$nestedMembers = Get-ADGroupMember -Identity $GroupName -recursive
$circular = $null
}
else {
$nestedMembers = Get-ADGroupMember -Identity $GroupName | sort objectclass -Descending
# if get adgroupmember returns nothing, it uses the members for ordinary getADGroup
if (!($nestedmembers)) {
$unknown = $ADGroupname | select -expand members
if ($unknown) {
$nestedmembers = @()
foreach ($member in $unknown) {
$nestedmembers += get-adobject $member
}
}
}
}
# loops through each member
ForEach($nestedmember in $nestedmembers){
# creates the properties into a custom object.
$Props = @{
Type = $nestedmember.objectclass;
Name = $nestedmember.name;
DisplayName = "";
ParentGroup = $ADgroupname.name;
Enabled = "";
Nesting = $nesting;
DN = $nestedmember.distinguishedname;
Comment = ""
EmployeeNumber = "";
LastLogonDate = "";
PasswordLastSet = "";
}
# if member object is a user
if ($nestedmember.objectclass -eq "user") {
# saves all the properties in the table.
$nestedADMember = get-aduser $nestedmember.Name -properties enabled, displayname, EmployeeNumber, LastLogonDate, PasswordLastSet
$table = new-object psobject -property $props
$table.enabled = $nestedadmember.enabled
$table.name = $nestedadmember.samaccountname
$table.displayname = $nestedadmember.displayname
$table.EmployeeNumber = $nestedadmember.EmployeeNumber
$table.LastLogonDate = $nestedadmember.LastLogonDate
$table.PasswordLastSet = $nestedadmember.PasswordLastSet
#save all in 1 storage
$resultHOlder += $table | select type, name, displayname, parentgroup, nesting, enabled, dn, comment , EmployeeNumber, LastLogonDate, PasswordLastSet
}
# if member object is group
elseif ($nestedmember.objectclass -eq "group") {
$table = new-object psobject -Property $props
# if circular, meaning the groups member of list contains one of its members.
# e.g. if group 2 is a member of group 1 and group 1 is a member of grou 2
if ($memberof -contains $nestedmember.distinguishedname) {
$table.comment = "Circular membership"
$circular = 1
}
# for circular output
#$table | select type, name, displayname, parentgroup, nesting, enabled, dn, comment
#calling function itself
$resultHOlder += Get-ADUsers -GroupName $nestedmember.distinguishedName
}
else {
if ($nestedmember) {
$table = new-object psobject -property $props
$resultHolder += $table | select type, name, displayname, parentgroup, nesting, enabled, dn, comment, EmployeeNumber, LastLogonDate, PasswordLastSet
}
}
}
}
return $resultHOlder
}
function Get-NestedGroupUsers {
param (
[Parameter(Mandatory = $true)][String]$FileName,
[Parameter(Mandatory = $true)][String]$searchFileURL
)
$storageHolder = @()
# $storageHolder | Export-Csv -Path "C:\Users\demandx\Desktop\AD User Lists\$FileName.csv" -NoTypeInformation -Force
$groupList = Get-Content $searchFileURL #| ForEach-Object { $_ }
$groupList | ForEach-Object {
$allusers = Get-ADUsers -GroupName $_
$storageHolder += $allusers
}
$storageHolder | select ParentGroup, Name, EmployeeNumber, Enabled, LastLogonDate, PasswordLastSet |Export-Csv -Path "C:\Users\demandx\Desktop\$FileName.csv" -NoTypeInformation -Force
}
# get members of the group and member of
$ADGroupname = get-adgroup $groupname -properties memberof, members
# list all members as list (no headers) and save to var
$memberof = $adgroupname | select -expand memberof
if ($adgroupname) {
if ($circular) {
$nestedMembers = Get-ADGroupMember -Identity $GroupName -recursive
$circular = $null
}
else {
$nestedMembers = Get-ADGroupMember -Identity $GroupName | sort objectclass -Descending
# if get adgroupmember returns nothing, it uses the members for ordinary getADGroup
if (!($nestedmembers)) {
$unknown = $ADGroupname | select -expand members
if ($unknown) {
$nestedmembers = @()
foreach ($member in $unknown) {
$nestedmembers += get-adobject $member
}
}
}
}
# loops through each member
ForEach($nestedmember in $nestedmembers){
# creates the properties into a custom object.
$Props = @{
Type = $nestedmember.objectclass;
Name = $nestedmember.name;
DisplayName = "";
ParentGroup = $ADgroupname.name;
Enabled = "";
Nesting = $nesting;
DN = $nestedmember.distinguishedname;
Comment = ""
EmployeeNumber = "";
LastLogonDate = "";
PasswordLastSet = "";
}
# if member object is a user
if ($nestedmember.objectclass -eq "user") {
# saves all the properties in the table.
$nestedADMember = get-aduser $nestedmember.Name -properties enabled, displayname, EmployeeNumber, LastLogonDate, PasswordLastSet
$table = new-object psobject -property $props
$table.enabled = $nestedadmember.enabled
$table.name = $nestedadmember.samaccountname
$table.displayname = $nestedadmember.displayname
$table.EmployeeNumber = $nestedadmember.EmployeeNumber
$table.LastLogonDate = $nestedadmember.LastLogonDate
$table.PasswordLastSet = $nestedadmember.PasswordLastSet
#save all in 1 storage
$resultHOlder += $table | select type, name, displayname, parentgroup, nesting, enabled, dn, comment , EmployeeNumber, LastLogonDate, PasswordLastSet
}
# if member object is group
elseif ($nestedmember.objectclass -eq "group") {
$table = new-object psobject -Property $props
# if circular, meaning the groups member of list contains one of its members.
# e.g. if group 2 is a member of group 1 and group 1 is a member of grou 2
if ($memberof -contains $nestedmember.distinguishedname) {
$table.comment = "Circular membership"
$circular = 1
}
# for circular output
#$table | select type, name, displayname, parentgroup, nesting, enabled, dn, comment
#calling function itself
$resultHOlder += Get-ADUsers -GroupName $nestedmember.distinguishedName
}
else {
if ($nestedmember) {
$table = new-object psobject -property $props
$resultHolder += $table | select type, name, displayname, parentgroup, nesting, enabled, dn, comment, EmployeeNumber, LastLogonDate, PasswordLastSet
}
}
}
}
return $resultHOlder
}
Parallel result
-------------------------------------------
Days : 0
Hours : 0
Minutes : 1
Seconds : 2
Milliseconds : 283
Ticks : 622833415
TotalDays : 0.000720872008101852
TotalHours : 0.0173009281944444
TotalMinutes : 1.03805569166667
TotalSeconds : 62.2833415
TotalMilliseconds : 62283.3415
Non parallel Result
-------------------------------------------
Days : 0
Hours : 0
Minutes : 0
Seconds : 35
Milliseconds : 322
Ticks : 353221537
TotalDays : 0.00040882122337963
TotalHours : 0.00981170936111111
TotalMinutes : 0.588702561666667
TotalSeconds : 35.3221537
TotalMilliseconds : 35322.1537