header1   header
header
header Register : : Login header
header
connector   connector
menuleft menuright
submenu   submenu
left
Powershell Memory
Last Post 01 Jul 2010 08:46 AM by James. 22 Replies.
Printer Friendly
  •  
  •  
  •  
  •  
  •  
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages Not Resolved
JamesUser is Offline
Basic Member
Basic Member
Posts:374
Avatar

--
29 Jun 2010 07:52 AM
    Hello,

    I am just wondering is there a way to sort out the memory that Powershell uses?

    When running massive scripts which take up all the memory in the server I am running it on (which is 4GB!) it slows everything down as you would expect.

    Is there anything I can put in my script to keep it down so the speed of the box is not dead?

    Many Thanks

    James
    JamesUser is Offline
    Basic Member
    Basic Member
    Posts:374
    Avatar

    --
    01 Jul 2010 03:41 AM
    Does anyone know how a single script can hog 4GB of RAM? and if so how do I stop it from hogging it? or release it as it loops?

    Many Thanks

    James
    George HowarthUser is Offline
    Basic Member
    Basic Member
    Posts:360
    Avatar

    --
    01 Jul 2010 03:55 AM
    Post your script. Maybe we can optimize it.
    Shay LevyUser is Offline
    PowerShell MVP, Admin
    Veteran Member
    Veteran Member
    Posts:1362
    Avatar

    --
    01 Jul 2010 04:02 AM
    Very easily:

    consider this:

    foreach($i in 1..100MB) {...}

    vs.

    1..100MB | foreach-object {...}


    Can you share the code?

    Shay Levy
    Windows PowerShell MVP
    http://PowerShay.com
    PowerShell Community Toolbar
    Twitter: @ShayLevy
    JamesUser is Offline
    Basic Member
    Basic Member
    Posts:374
    Avatar

    --
    01 Jul 2010 05:08 AM
    Hello,

    I can share the code yes however I will take certain parts out which relate to our domain structure.

    # Set Parameters Function New-Year { param ( [switch]$All, [switch]$Stage1, [switch]$Stage2, [switch]$Stage3, [switch]$Stage4, [switch]$Help ) # Set Variables $Global:S = $Null $Global:StartRoutine = $null $Global:FinishRoutine = $null $Global:Stage1Run = $null $Global:Stage2Run = $null $Global:Stage3Run = $null $Global:Stage4Run = $null $Global:Stage1Start = $null $Global:Stage2Start = $null $Global:Stage3Start = $null $Global:Stage4Start = $null $Global:Stage1Finish = $null $Global:Stage2Finish = $null $Global:Stage3Finish = $null $Global:Stage4Finish = $null $Global:TimeRoutine = $null $Global:TimeStage1 = $null $Global:TimeStage2 = $null $Global:TimeStage3 = $null $Global:TimeStage4 = $null $Global:Switches = $null $Global:SchoolList = Import-Csv "C:\Powershell\CSV\SchoolsList.csv" Function Usage { Write-Host "" Write-Host "FUNCTION NAME: New-Year" -ForegroundColor White Write-Host "" Write-Host "USAGE" Write-Host " New-Year -All " Write-Host " New-Year -Stage1" Write-Host " New-Year -Stage1 -Stage2" Write-Host " New-Year -Stage1 -Stage2 -Stage3" Write-Host "" Write-Host "DESCRIPTION:" Write-Host " Designed for the use of the schools team for a new intake of students, parents etc." Write-Host " It can be used for one particular operation or all operations required" Write-Host " for the new intake. It will also give you the statistics of time taken at the end." Write-Host "" Write-Host "AVAILABLE SWITCHES:" Write-Host " -All : Runs All of the stages in order" Write-Host " -Stage1 : Runs Stage 1 - Removing Of Disabled Users" Write-Host " -Stage2 : Runs Stage 2 - Removing Of Spaces In The SAMAccountName,UPN, Mail Attributes" Write-Host " -Stage3 : Runs Stage 3 - Sets Student Target And Proxy Addresses " Write-Host " -Stage4 : Runs Stage 4 - Sets City And Company Information For Users" Write-Host "" Write-Host "REQUIREMENTS:" Write-Host " You must provide at lease one switch" Write-Host "" break } Function All { Stage1 Stage2 Stage3 Stage4 } Function RoutineStart { Write-Host " " Write-Host " ROUTINE START: " -ForegroundColor White Write-Host " " $Global:StartRoutine = Get-Date " Day: " + $Global:StartRoutine.DayOfWeek " Date: " + $Global:StartRoutine.ToShortDateString() " Time: " + $Global:StartRoutine.ToShortTimeString() Write-Host " " } Function Stage1 { #Remove Disabled Users $Global:Stage1Run = 1 Write-Host " Stage 1: Removing Disabled Users.... " -ForegroundColor Yellow $Global:Stage1Start = Get-Date Write-Host " " $SchoolList | ForEach-Object{ $School = $_.School $ou = 'OU=users,OU=' + $School + ',OU=foo1,DC=foo,DC=co,DC=uk' Get-QADUser -Title "student", "teacher","staff","parent" -SearchRoot $ou -SizeLimit 0 -IncludeAllProperties | Where-Object {$_.useraccountcontrol -eq 514 -or $_.useraccountcontrol -eq 66050 }| ForEach-Object{ $SamAccountName = $_.SamAccountName Write-Host "Deleting User: " $SamAccountName Delete-ADUser $SamAccountName } } Write-Host " " Write-Host " Stage 1 Complete! Disabled Users Successfully Removed. " -ForegroundColor Yellow $Global:Stage1Finish = Get-Date Write-Host " " Write-Host " " } Function Stage2 { $Global:Stage2Run = 1 # Remove Spaces Write-Host " Stage 2: Removing Spaces From Accounts.... " -ForegroundColor Yellow $Global:Stage2Start = Get-Date Write-Host " " $SchoolList | ForEach-Object{ $School = $_.School $ou = 'OU=users,OU=' + $School + ',OU=foo1,DC=foo,DC=co,DC=uk' Get-QADUser -Title "student", "teacher","staff","parent" -SearchRoot $OU -SizeLimit 0 -includeAllProperties |Where-Object {$_.UserPrincipalName -match "\s" -or $_.samAccountName -match "\s" -or $_.mail -match "\s"}| ForEach-Object{ $Sam = $_.SamAccountName $Sam1 = $Sam -replace " ","" $NewSam = $Sam1 -replace "'","" $UPN = $_.UserPrincipalName $UPN1 = $UPN -replace " ","" $NewUPN = $UPN1 -replace "'","" $Mail = $_.Mail $Mail1 = $Mail -replace " ","" $NewMail = $Mail1 -replace "'","" Set-QADUser -Identity $Sam -ObjectAttributes @{Mail = $NewMail} Set-QADUser -Identity $Sam -UserPrincipalName $NewUPN Set-QADUser -Identity $Sam -SamAccountName $NewSam } } Write-Host " " Write-Host " Stage 2 Complete! Spaces Successfully Removed. " -ForegroundColor Yellow $Global:Stage2Finish = Get-Date Write-Host " " Write-Host " " } Function Stage3 { $Global:Stage3Run = 1 Write-Host " Stage 3: Setting Student Proxy and Target Addresses.... " -ForegroundColor Yellow $Global:Stage3Start = Get-Date Write-Host " " # Assign Target Address and Proxy Address to Students $SchoolList | ForEach-Object{ $School = $_.School $ou = 'OU=users,OU=' + $School + ',OU=foo1,DC=foo,DC=co,DC=uk' Get-QADUser -Title "student" -SearchRoot $OU -SizeLimit 0 | ForEach-Object{ $TargetAddress = 'smtp:' + $_.samAccountName + '@foo1.co.uk' $ProxyAddress = 'SMTP:' + $_.samAccountName + '@' + $School + '.foo.co.uk' Set-QADUser -Identity $_.Name -PasswordNeverExpires $false Set-QADUser -Identity $_.Name -ObjectAttributes @{TargetAddress=$TargetAddress} Set-QADUser -Identity $_.Name -ObjectAttributes @{ProxyAddresses=$ProxyAddress} } } Write-Host " " Write-Host " Stage 3 Complete! Target and Proxy Addresses Successfully Written. " -ForegroundColor Yellow $Global:Stage3Finish = Get-Date Write-Host " " Write-Host " " } Function Stage4 { $Global:Stage4Run = 1 Write-Host " Stage 4: Setting City And Company Information.... " -ForegroundColor Yellow $Global:Stage4Start = Get-Date Write-Host " " # Write City And Company Information $SchoolList| ForEach-Object{ $School = $_.School $ou = 'OU=users,OU=' + $School + ',OU=foo1,DC=foo,DC=co,DC=uk' Get-QADUser -SearchRoot $OU -sizeLimit 0 | ForEach-Object{ $Sam = $_.SamAccountName Set-QADUser -Identity $Sam -Company $School -City "city1" } } Write-Host " " Write-Host " Stage 4 Complete! City And Company Information Successfully Written. " -ForegroundColor Yellow $Global:Stage4Finish = Get-Date Write-Host " " Write-Host " " } Function RoutineFinish { Write-Host " All Stages Complete! " -ForegroundColor White Write-Host " " Write-Host " " Write-Host " ROUTINE END: " -ForegroundColor White Write-Host " " $Global:FinishRoutine = Get-Date " Day: " + $Global:FinishRoutine.DayOfWeek " Date: " + $Global:FinishRoutine.ToShortDateString() " Time: " + $Global:FinishRoutine.ToShortTimeString() Write-Host " " Write-Host " " Write-Host " Routine Statistics: " Write-Host " ------------------- " Write-Host " " Write-Host " " # Work Out Time Taken $TimeRoutine = New-TimeSpan -Start $StartRoutine -End $FinishRoutine if ($Stage1 -or $All) { $TimeStage1 = New-TimeSpan -Start $Stage1Start -End $Stage1Finish } if ($Stage2 -or $All) { $TimeStage2 = New-TimeSpan -Start $Stage2Start -End $Stage2Finish } if ($Stage3 -or $All) { $TimeStage3 = New-TimeSpan -Start $Stage3Start -End $Stage3Finish } if ($Stage4 -or $All) { $TimeStage4 = New-TimeSpan -Start $Stage4Start -End $Stage4Finish } # Give Statistics Write-Host " Routine Start: $($StartRoutine.DayOfWeek) $($StartRoutine)" Write-Host " " If($Stage1Run -ne "1") { Write-Host " " Write-Host " Statistics For Stage 1 Not Available (Stage 1 Was Not Run)" Write-Host " " } else { Write-Host " " Write-Host " Stage 1 Start: $($Stage1Start.DayOfWeek) $($Stage1Start)" Write-Host " Stage 1 Finish: $($Stage1Finish.DayOfWeek) $($Stage1Finish)" Write-Host " Stage 1 Complete Time: $([string]$TimeStage1.Days) Days $([string]$TimeStage1.Hours) Hours $([string]$TimeStage1.Minutes) Minutes $([string]$TimeStage1.Seconds) Seconds" Write-Host " " } If($Stage2Run -ne "1") { Write-Host " " Write-Host " Statistics For Stage 2 Not Available (Stage 2 Was Not Run)" Write-Host " " } else { Write-Host " " Write-Host " Stage 2 Start: $($Stage2Start.DayOfWeek) $($Stage2Start)" Write-Host " Stage 2 Finish: $($Stage2Finish.DayOfWeek) $($Stage2Finish)" Write-Host " Stage 2 Complete Time: $([string]$TimeStage2.Days) Days $([string]$TimeStage2.Hours) Hours $([string]$TimeStage2.Minutes) Minutes $([string]$TimeStage2.Seconds) Seconds" Write-Host " " } If($Stage3Run -ne "1") { Write-Host " " Write-Host " Statistics For Stage 3 Not Available (Stage 3 Was Not Run)" Write-Host " " } else { Write-Host " " Write-Host " Stage 3 Start: $($Stage3Start.DayOfWeek) $($Stage3Start)" Write-Host " Stage 3 Finish: $($Stage3Finish.DayOfWeek) $($Stage3Finish)" Write-Host " Stage 3 Complete Time: $([string]$TimeStage3.Days) Days $([string]$TimeStage3.Hours) Hours $([string]$TimeStage3.Minutes) Minutes $([string]$TimeStage3.Seconds) Seconds" Write-Host " " } If($Stage4Run -ne "1") { Write-Host " " Write-Host " Statistics For Stage 4 Not Available (Stage 4 Was Not Run)" Write-Host " " } else { Write-Host " " Write-Host " Stage 4 Start: $($Stage4Start.DayOfWeek) $($Stage4Start)" Write-Host " Stage 4 Finish: $($Stage4Finish.DayOfWeek) $($Stage4Finish)" Write-Host " Stage 4 Complete Time: $([string]$TimeStage4.Days) Days $([string]$TimeStage4.Hours) Hours $([string]$TimeStage4.Minutes) Minutes $([string]$TimeStage4.Seconds) Seconds" Write-Host " " } Write-Host " " Write-Host " Routine Finish: $($FinishRoutine.DayOfWeek) $($FinishRoutine)" Write-Host " " Write-Host " " Write-Host " Routine Complete Time: $([string]$TimeRoutine.Days) Days $([string]$TimeRoutine.Hours) Hours $([string]$TimeRoutine.Minutes) Minutes $([string]$TimeRoutine.Seconds) Seconds" Write-Host " " Write-Host " " Write-Host " End Of Routine Statistics" Write-Host " " Write-Host " " } if (!($All -or $Stage1 -or $Stage2 -or $Stage3 -or $Stage4 -or $Help)) { Write-Host " " Write-Host "Please Select A Switch" Write-Host " " ; break} else { if($All) {$Global:S += "All "} if($Stage1) {$Global:S += "Stage1 "} if($Stage2) {$Global:S += "Stage2 "} if($Stage3) {$Global:S += "Stage3 "} if($Stage4) {$Global:S += "Stage4 "} if($Help) { Usage break } } RoutineStart if($S -match "All") {All} if($S -match "Stage1") {Stage1} if($S -match "Stage2") {Stage2} if($S -match "Stage3") {Stage3} if($S -match "Stage4") {Stage4} RoutineFinish }

    Its using 4GB of ram when it just runs stage3 and nothing else on the server is doing anything hence it kills the server and slows it all down.


    Shay, I am not too sure what your getting at with your foreach's could you elaborate a little more?

    And are there any guidelines for anything in future? So how to better manage memory (Shay I presume you were meaning this however I am unsure of your meaning)

    Many Thanks

    James
    halr9000User is Offline
    PowerShell MVP, Site Admin
    Advanced Member
    Advanced Member
    Posts:565
    Avatar

    --
    01 Jul 2010 05:26 AM
    1. You will like the v2 comment-based help, you may want to check that out.
    2. How big is this csv file?
    Community Director, PowerShellCommunity.org
    Co-host, PowerScripting Podcast
    Author, TechProsaic
    JamesUser is Offline
    Basic Member
    Basic Member
    Posts:374
    Avatar

    --
    01 Jul 2010 05:42 AM
    The csv file contains a list of 127 school names and thats all nothing else just one column.

    Its size is 2K

    Comment Based help in v2? How do you mean?

    Many Thanks

    James
    George HowarthUser is Offline
    Basic Member
    Basic Member
    Posts:360
    Avatar

    --
    01 Jul 2010 05:46 AM
    This can be simplified/optimized. I don't have time today, but I'll see what I can do tomorrow.
    Bartek BielawskiUser is Offline
    New Member
    New Member
    Posts:43
    Avatar

    --
    01 Jul 2010 05:50 AM
    Quick one: if you want disabled accounts, tell Quest Cmdlet to return only those (-Disabled)
    That should save you a lot of time and effort in Stage1.
    JamesUser is Offline
    Basic Member
    Basic Member
    Posts:374
    Avatar

    --
    01 Jul 2010 06:07 AM
    Hello,

    I have just found the help file for that.

    Many Thanks for that it makes it a little neater!

    James
    JamesUser is Offline
    Basic Member
    Basic Member
    Posts:374
    Avatar

    --
    01 Jul 2010 06:25 AM
    Hello,

    I thought the same however I thought it would put too much memroy usage on it doing that though but thinking about it now would that not be teh equal amount of time for my code and yours to execute?

    Many Thanks

    James
    JamesUser is Offline
    Basic Member
    Basic Member
    Posts:374
    Avatar

    --
    01 Jul 2010 06:41 AM
    I stand corrected! I have just run it and changed the following:

    Get-QADUser -Title "student", "teacher","staff","parent" -SearchRoot $ou -SizeLimit 0 -Disabled | # -IncludeAllProperties Only if using Account Control
    # Where-Object {$_.useraccountcontrol -eq 514 -or $_.useraccountcontrol -eq 66050 }|
    ForEach-Object{

    and it took minutes and deleted around 30 accounts!!!!

    Many Thanks

    James
    JamesUser is Offline
    Basic Member
    Basic Member
    Posts:374
    Avatar

    --
    01 Jul 2010 06:46 AM
    Oh just an after thought would that catch the disabled users which have the "Password Never Expires" checked?

    So in otherworks the user account control of: 66050

    I have just tried it and its not removing them users....

    Does anyone know why this is? or would I have to run something else to catch them too?

    Many Thanks

    James
    glnsizeUser is Offline
    Basic Member
    Basic Member
    Posts:193

    --
    01 Jul 2010 06:50 AM
    I ran through and did a quick optimization of you're script... A couple of points you use -IncludeAllProperties ALOT.  That will increase you're memory utilization, b/c powershell must process all those properties.  Pair that down to what you need.  Also you're using where-object to do all the filtering, that's fine, but it will increase the footprint.  Consider moving that logic into a LDAP filter, it will not only be faster, but use WAY less memory as well. 

    DO NOT RUN THIS IN A LIVE ENV... I just did a re-write I haven't even tried to run this script.  Read through it and note the changes, this is only an example.

    <#
        .SYNOPSIS
            Designed for the use of the schools team for a new intake of students, parents etc.
            It can be used for one particular operation or all operations required
            for the new intake. It will also give you the statistics of time taken at the end.
        .DESCRIPTION
            Designed for the use of the schools team for a new intake of students, parents etc.
            It can be used for one particular operation or all operations required
            for the new intake. It will also give you the statistics of time taken at the end.
        .PARAMETER ALL
            Will run all options. (DEFAULT)
        .PARAMETER File
            Path to a CSV file containg the new students
        .PARAMETER DisabledUsers
            Removing Of Disabled Users
        .PARAMETER Spaces
            Removing Of Spaces In The SAMAccountName,UPN, Mail Attributes
        .PARAMETER StudentInfo
            Sets Student Target And Proxy Addresses
        .PARAMETER LocationInfo
            Sets City And Company Information For Users
        .EXAMPLE 
            ./New-Year.ps1 -Path 'C:\Powershell\CSV\SchoolsList.csv' -All
        .EXAMPLE
            ./New-Year.ps1 -Path 'C:\Powershell\CSV\SchoolsList.csv' -DisabledUsers
        .EXAMPLE
            ./New-Year.ps1 -Path 'C:\Powershell\CSV\SchoolsList.csv' -DisabledUsers -Spaces -StudentInfo
    #>                   
    [CmdletBinding(DefaultParameterSetName='ALL')]                 
    param                         
    (                        
        [Parameter(Mandatory=$true,ParameterSetName='All',HelpMessage ="Path to the CSV containing the list of Schools")]                        
        [Parameter(Mandatory=$true,ParameterSetName='Selective',HelpMessage ="Path to the CSV containing the list of Schools")]                      
        [ValidateScript({Test-Path -Path $_})]            
        [String]                        
        $File            
    ,                        
        [Parameter(Mandatory=$false,ParameterSetName='All')]                        
        [switch]                        
        $All                        
    ,                        
        [Parameter(ParameterSetName='Selective')]                        
        [switch]                        
        $DisabledUsers                        
    ,                        
        [Parameter(ParameterSetName='Selective')]                        
        [switch]                        
        $Spaces                        
    ,                        
        [Parameter(ParameterSetName='Selective')]                        
        [switch]                        
        $StudentInfo                        
    ,                        
        [Parameter(ParameterSetName='Selective')]                        
        [switch]                        
        $LocationInfo                        
    )                        
    Begin             
    {            
        #Remove Disabled Users                        
        Function Remove-DisabledUsers                         
        {                        
            Param(                        
                [Parameter(Mandatory=$true)]                        
                [string[]]$SchoolList                        
            )                        
            $start = Get-date                        
                            
            Write-verbose "$(get-date -format g) Starting Removing Disabled Users.... "                        
                            
            Foreach ($School in $SchoolList)                        
            {                        
                $ou = 'OU=users,OU=' + $School + ',OU=foo1,DC=foo,DC=co,DC=uk'                        
                Get-QADUser -Title "student", "teacher","staff","parent" `
                    -SearchRoot $ou `
                    -SizeLimit 0 `
                    -IncludeAllProperties |                        
                    Where-Object {$_.useraccountcontrol -eq 514 -or $_.useraccountcontrol -eq 66050 }|                        
                    Delete-ADUser                        
            }                        
                                   
            Write-verbose "$(get-date -format g) Finished Removing Disabled Users.... "                        
            Write-verbose "User cleanup completed in $((New-TimeSpan -Start $start).TotalMinutes) Minutes"                        
        }                        
                                
        # Remove Spaces                        
        Function Remove-SpacesFromAccounts             
        {                        
            Param(                        
                [Parameter(Mandatory=$true)]                        
                [string[]]$SchoolList                        
            )                        
            $Start = Get-Date                        
            Write-Verbose "$(get-date -format g) Removing Spaces From Accounts.... "                        
                            
            Foreach ($School in $SchoolList)                        
            {                        
                $ou = 'OU=users,OU=' + $School + ',OU=foo1,DC=foo,DC=co,DC=uk'                        
                $Users = Get-QADUser -Title "student", "teacher","staff","parent" `
                    -SearchRoot $OU `
                    -SizeLimit 0 `
                    -includeAllProperties |                        
                    Where-Object {$_.UserPrincipalName -match "\s" -or $_.samAccountName -match "\s" -or $_.mail -match "\s"}                        
                                        
                Foreach ($User in $Users)                        
                {                        
                    $Sam = $User.SamAccountName                        
                    $Sam1 = $Sam -replace " ",""                        
                    $NewSam = $Sam1 -replace "'",""                        
                            
                    $UPN = $User.UserPrincipalName                        
                    $UPN1 = $UPN -replace " ",""                        
                    $NewUPN = $UPN1 -replace "'",""                        
                            
                    $Mail = $User.Mail                        
                    $Mail1 = $Mail -replace " ",""                        
                    $NewMail = $Mail1 -replace "'",""                        
                            
                    Set-QADUser -Identity $Sam -ObjectAttributes @{Mail = $NewMail}                        
                    Set-QADUser -Identity $Sam -UserPrincipalName $NewUPN                        
                    Set-QADUser -Identity $Sam -SamAccountName $NewSam                        
                }                        
            }                        
            Write-verbose "$(get-date -format g) Finished Removing spaces from accounts"                        
            Write-verbose "Space removal completed in $((New-TimeSpan -Start $start).TotalMinutes) Minutes"                        
        }                        
                                
        Function Set-StudentInfo             
        {                        
            Param(                        
                [Parameter(Mandatory=$true)]                        
                [string[]]$SchoolList                        
            )                        
            $start = Get-date                        
                                    
            Write-Verbose "$(get-date -format g) Setting Student Proxy and Target Addresses.... "                        
            # Assign Target Address and Proxy Address to Students                        
                            
            Foreach ($School in $SchoolList)                        
            {                        
                $ou = 'OU=users,OU=' + $School + ',OU=foo1,DC=foo,DC=co,DC=uk'                        
                                        
                $users = Get-QADUser -Title "student" -SearchRoot $OU -SizeLimit 0                         
                                        
                Foreach ($user in $users)                        
                {                        
                    $TargetAddress = 'smtp:{0}@foo1.co.uk' -f $user.samAccountName                        
                    $ProxyAddress = 'SMTP:{0}@{1}.foo.co.uk' -f $user.samAccountName ,$School                        
                            
                    Set-QADUser -Identity  $user.Name -PasswordNeverExpires $false                         
                    Set-QADUser -Identity  $user.Name -ObjectAttributes @{TargetAddress=$TargetAddress}                        
                    Set-QADUser -Identity  $user.Name -ObjectAttributes @{ProxyAddresses=$ProxyAddress}                        
                }                        
            }                        
                                    
            Write-Verbose "$(get-date -format g) Setting Student Proxy and Target Addresses.... "                        
            Write-Verbose "completed Setting student info in $((New-TimeSpan -Start $start).TotalMinutes) Minutes"                        
                            
        }                        
                                
        Function Set-LocationInfo             
        {                        
            Param(                        
                [Parameter(Mandatory=$true)]                        
                [string[]]$SchoolList                        
            )                        
            $start = Get-date                        
                                    
            Write-Verbose "$(get-date -format g) Setting City And Company Information...."                        
            # Write City And Company Information                        
                            
            Foreach ($School in $SchoolList)                        
            {                        
                $ou = 'OU=users,OU=' + $School + ',OU=foo1,DC=foo,DC=co,DC=uk'                        
                            
                Get-QADUser -SearchRoot $OU -sizeLimit 0 |                        
                    Set-QADUser -Company $School -City "city1"                           
            }                        
                                    
            Write-Verbose "$(get-date -format g) City And Company Information Successfully Written. " -ForegroundColor Yellow                        
            Write-Verbose "completed Setting city, and company info in $((New-TimeSpan -Start $start).TotalMinutes) Minutes"                        
        }                        
    }                        
    End                        
    {                     
        $SchoolList = Import-Csv -Path $File                        
                                   
        IF ($PSCMDLET.ParameterSetName -eq "All" -OR $DisabledUsers)                        
        {                        
            Remove-DisabledUsers -SchoolList $SchoolList                        
        }                        
        IF ($PSCMDLET.ParameterSetName -eq "All" -OR $Spaces)                        
        {                        
            Remove-SpacesFromAccounts -SchoolList $SchoolList                        
        }                        
        IF ($PSCMDLET.ParameterSetName -eq "All" -OR $StudentInfo)                        
        {                        
            Set-StudentInfo -SchoolList $SchoolList                        
        }                        
        IF ($PSCMDLET.ParameterSetName -eq "All" -OR $LocationInfo)                        
        {                        
            Set-LocationInfo -SchoolList $SchoolList                        
        }                        
    }

    Hope that helps,
    ~Glenn

    UPDATE: Forgot the cmdletbinding statement...
    Bartek BielawskiUser is Offline
    New Member
    New Member
    Posts:43
    Avatar

    --
    01 Jul 2010 06:54 AM
    Well, it has nothing to do with disabled account, right? ;)
    But do not worry - Quest knew you will need it, so you have -PasswordNeverExpires switch there too. ;)
    But those two loops should be quicker than the one you had anyway... Since you ask AD only for accounts you want to process, and don't waste time and resources to filter them on your side.
    Shay LevyUser is Offline
    PowerShell MVP, Admin
    Veteran Member
    Veteran Member
    Posts:1362
    Avatar

    --
    01 Jul 2010 06:55 AM
    Get-QADUser -SizeLimit 0 -Disabled -PasswordNeverExpires:$true


    foreach($i in 1..1000000000) { do something}

    is not the same as

    1..1000000000 | foreach { do something}


    The first will blow your memory off because it tries to gather all 1000000000 objects first. The latter will do the same in a streaming way, one at a time, no performance penalty or memory issues.

    Shay Levy
    Windows PowerShell MVP
    http://PowerShay.com
    PowerShell Community Toolbar
    Twitter: @ShayLevy
    Shay LevyUser is Offline
    PowerShell MVP, Admin
    Veteran Member
    Veteran Member
    Posts:1362
    Avatar

    --
    01 Jul 2010 07:01 AM
    You can save some precious round trips to AD:


    Set-QADUser -Identity $Sam -EMail $NewMail -UserPrincipalName $NewUPN -SamAccountName $NewSam

    Instead of:

    Set-QADUser -Identity $Sam -ObjectAttributes @{Mail = $NewMail}
    Set-QADUser -Identity $Sam -UserPrincipalName $NewUPN
    Set-QADUser -Identity $Sam -SamAccountName $NewSam




    And

    Set-QADUser -Identity $user.Name -PasswordNeverExpires $false -ObjectAttributes @{TargetAddress=$TargetAddress; ProxyAddresses=$ProxyAddress}


    Instead of:

    Set-QADUser -Identity $user.Name -PasswordNeverExpires $false
    Set-QADUser -Identity $user.Name -ObjectAttributes @{TargetAddress=$TargetAddress}
    Set-QADUser -Identity $user.Name -ObjectAttributes @{ProxyAddresses=$ProxyAddress}

    Shay Levy
    Windows PowerShell MVP
    http://PowerShay.com
    PowerShell Community Toolbar
    Twitter: @ShayLevy
    JamesUser is Offline
    Basic Member
    Basic Member
    Posts:374
    Avatar

    --
    01 Jul 2010 07:39 AM
    Ahhh Shay,

    So what I have in my code then is doing it in a streaming way then :)

    Also bielawb how would I get the disabled with -PasswordNeverExpires as I have tried adding another loop in and it just errors continually...

    I have done the following:

    Get-QADUser -Title "student", "teacher","staff","parent" -SearchRoot $ou -SizeLimit 0 -Disabled |
    ForEach-Object{

    $SamAccountName = $_.SamAccountName

    Write-Host "Deleting User: " $SamAccountName

    Delete-ADUser $SamAccountName

    }

    Get-QADUser -Title "student", "teacher","staff","parent" -SearchRoot $ou -SizeLimit 0 -PasswordNeverExpires $true -Disabled |
    ForEach-Object{

    $SamAccountName = $_.SamAccountName

    Write-Host "Deleting User: " $SamAccountName

    Delete-ADUser $SamAccountName

    }


    So in effect two loops and its just erroring saying:

    Get-QADUser : Cannot bind parameter 'Identity'. Cannot convert value "True" to type "Quest.ActiveRoles.ArsPowerShellSna
    pIn.Data.IdentityParameter". Error: "Invalid cast from 'System.Boolean' to 'Quest.ActiveRoles.ArsPowerShellSnapIn.Data.
    IdentityParameter'."


    glnsize - I will have a look at it and throw it as my test boxes :) and I am not to sure on the ldap queries as I have never done them before could you show me an example as something to work off?

    Many Thanks

    James

    Many Thanks

    James
    JamesUser is Offline
    Basic Member
    Basic Member
    Posts:374
    Avatar

    --
    01 Jul 2010 07:52 AM
    Hello,

    glnsize I have just ran your code and its coming up with:

    C:\powershell\Scripts\new-Year.ps1 : A parameter cannot be found that matches parameter name 'Path'.
    At line:1 char:21

    I am not entierly sure what its referring to... Could you shed any light on the issue?

    Many Thanks

    James
    JamesUser is Offline
    Basic Member
    Basic Member
    Posts:374
    Avatar

    --
    01 Jul 2010 07:58 AM
    Shay,

    Thanks for that I have changed my code!

    Many Thanks

    James
    Shay LevyUser is Offline
    PowerShell MVP, Admin
    Veteran Member
    Veteran Member
    Posts:1362
    Avatar

    --
    01 Jul 2010 08:16 AM
    You're missing a colon:

    -PasswordNeverExpires:$true

    Shay Levy
    Windows PowerShell MVP
    http://PowerShay.com
    PowerShell Community Toolbar
    Twitter: @ShayLevy
    glnsizeUser is Offline
    Basic Member
    Basic Member
    Posts:193

    --
    01 Jul 2010 08:24 AM

    That's what I get for not testing it first... sorry about that I forgot the CmdletBinding statement... I updated the code.

    Anyways Shay is you're man when it comes to the AD Stuff.  I was more trying to highlight the work flow and some of the v2 features (comment based help, parameter binding, validation, etc...)

    As an aside after going through this script... unless your domain is really massive (i don't think it is or your original script shouldn't have worked) your target should be -le 10 min.  If this script takes longer than 10 min you still have some more optimizations to do.

    Hope that helps,
    ~Glenn

    p.s. sorry to script and run, but my wife would like to leave on vacation....

    JamesUser is Offline
    Basic Member
    Basic Member
    Posts:374
    Avatar

    --
    01 Jul 2010 08:46 AM
    Thanks for that Shay!

    I just thought I could set them all to neverexpire before the script runs and then I dont have to go through and check again! :) But I will see what happens and failing that I will chuck it right in there! :)

    Our domain consists of 127 schools with information from all the parents, students, teachers and staff within each of the schools! 1 account per person! So were running a fair few accounts! So its pretty big!

    Thats fine I will have another pop with the code and post back my findings! :)

    Many Thanks

    James
    You are not authorized to post a reply.


    Active Forums 4.3
    right
    footer   footer
    footer Sponsored by Quest Software • SAPIEN Technologies • Compellent • Microsoft Windows Server 2008 R2 footer
    footer   footer