2
\$\begingroup\$

I am pretty new to powershell and I'm not great at coding, but I have managed to cobble together code from around the net to help save time when removing old students accounts in AD.

Code currently does the following;

  • Takes leavers from .csv file
  • Moves the leavers to leavers OU, Disables Account, and removes from all groups
  • Moves their home folder to the Leavers Archive share
  • Deletes their profiles .v5 and .v6 folders

What I'm hoping is that someone can take a look at the code and possibly explain how it could be tidied and cleaned up and condensed if possible, We have 4 different shares split A-D, E-J, K-R, S-Z

In order to do what I needed for each share I just duplicated the code for each share.

Here's the code.

################################################################################

#Disables Student accounts for leavers and moves them to the leavers OU
#Disables Parent Accounts, Strips groups, Moves to Parent Leavers OU

    ################################################################################

    #Import users to be disabled

    ################################################################################
    Import-Module ActiveDirectory
    #Create working directory
    #New-Item -ItemType directory "C:\LeaversExports"

    Import-Csv "C:\Leavers.csv" | ForEach-Object {
    $samAccountName = $_."samAccountName"
    Get-ADUser -Identity $samAccountName | Disable-ADAccount
    Write-host -ForegroundColor Green "$samAccountName Disabled"
    }

    ################################################################################
    #Move users from SD1 to Leavers SD1
    $SD1 = "OU=SD1,OU=Students,DC=Contoso,DC=ac,DC=uk"
    $SD1Leavers = "OU=Leavers SD1,OU=Students,OU=Leavers,DC=Contoso,DC=ac,DC=uk"
    Get-ADUser -filter {Enabled -eq $false } -SearchBase $SD1 -properties name,samaccountname,DistinguishedName,homedirectory,ProfilePath |select SamAccountName,homedirectory,ProfilePath | export-csv C:\LeaversExports\SD1_Leavers.csv -nti
    Search-ADAccount –AccountDisabled –UsersOnly –SearchBase $SD1 | Move-ADObject –TargetPath $SD1Leavers
    Write-Host -ForegroundColor Green "SD1 - Disabled users Moved"


    # Remove User from All Group Memberships
    $Users = Get-ADUser -SearchBase $SD1Leavers -Filter *
    Get-ADGroup -Filter * | Remove-ADGroupMember -Members $users -Confirm:$False


    $users = Get-ADUser -SearchBase $SD1Leavers -Filter * 

    foreach($user in $users){
      $groups = Get-ADPrincipalGroupMembership $user.SamAccountName | Where-Object {$_.name -NotLike '*Domain*'}
      foreach($group in $groups){

        Remove-ADGroupMember -Identity $group -Members $user -erroraction silentlycontinue

      }
    }
    Write-Host -ForegroundColor Green "SD1 Leavers removed from all Groups"

    #Move SD1 Leavers Home Area to Archive
    $CSVPath      = 'C:\LeaversExports\SD1_Leavers.csv'
    $NewHomeRoot  = '\\FS1\A-D Leavers$\Leavers 18-19$'
    #$NewHomeLocal = 'D:\Data\Users'

    $Users = Import-Csv $CSVPath

    foreach( $User in $Users ){
        $NewHome   = Join-Path -Path $NewHomeRoot -ChildPath $User.SamAccountName

        Robocopy.exe $User.homedirectory $NewHome /MIR /MOVE

        }
    Write-Host -ForegroundColor Green "All SD1 Leavers Home Folders Moved to Archive"

    #Delete Profile Folders
    $CSVPath = 'C:\LeaversExports\SD1_Leavers.csv'
    $Users = Import-Csv $CSVPath
    $samAccountName = $Users.SamAccountName
    $profilepathv6 = $Users.ProfilePath + ".V6"
    $profilepathv5 = $Users.ProfilePath + ".V5"

    foreach( $User in $Users ){
        if (Test-Path $profilepathv6){
        Write-Host -ForegroundColor Yellow "$profilepathv6 Path Found"
        Remove-Item ($profilepathv6)-Force -Confirm:$false
        Write-Host -ForegroundColor Green "$profilepathv6 - has been deleted"
        }
        Else{

        Write-Host -ForegroundColor Red ".V6 Path Not found - Skipped"

        }
        if (Test-Path $profilepathv5){
        Write-Host -ForegroundColor Yellow "$profilepathv5 Path Found"
        Remove-Item ($profilepathv5)-Force -Confirm:$false
        Write-Host -ForegroundColor Green "$profilepathv5 - has been deleted"
        }
            Else{

        Write-Host -ForegroundColor Red ".V5 Path Not found - Skipped"

        }
    }

    Write-Host -BackgroundColor Green -ForegroundColor Black "Profiles deleted"
    #Clean up working files
    #Remove-Item "C:\LeaversExports" -Force -recurse

    ################################################################################

    ################################################################################
    #Move users from SD2 to Leavers SD2
    $SD2 = "OU=SD2,OU=Students,DC=Contoso,DC=ac,DC=uk"
    $SD2Leavers = "OU=Leavers SD2,OU=Students,OU=Leavers,DC=Contoso,DC=ac,DC=uk"
    Get-ADUser -filter {Enabled -eq $false } -SearchBase $SD2 -properties name,samaccountname,DistinguishedName,homedirectory,ProfilePath |select SamAccountName,homedirectory,ProfilePath | export-csv C:\LeaversExports\SD2_Leavers.csv -nti
    Search-ADAccount –AccountDisabled –UsersOnly –SearchBase $SD2 | Move-ADObject –TargetPath $SD2Leavers
    Write-Host -ForegroundColor Green "SD2 - Disabled users Moved"


    # Remove User from All Group Memberships
    $Users = Get-ADUser -SearchBase $SD2Leavers -Filter *
    Get-ADGroup -Filter * | Remove-ADGroupMember -Members $users -Confirm:$False


    $users = Get-ADUser -SearchBase $SD2Leavers -Filter * 

    foreach($user in $users){
      $groups = Get-ADPrincipalGroupMembership $user.SamAccountName | Where-Object {$_.name -NotLike '*Domain*'}
      foreach($group in $groups){

        Remove-ADGroupMember -Identity $group -Members $user -erroraction silentlycontinue

      }
    }
    Write-Host -ForegroundColor Green "SD2 Leavers removed from all Groups"

    #Move SD2 Leavers Home Area to Archive
    $CSVPath      = 'C:\LeaversExports\SD2_Leavers.csv'
    $NewHomeRoot  = '\\FS1\E-J Leavers$\Leavers 18-19'
    #$NewHomeLocal = 'D:\Data\Users'

    $Users = Import-Csv $CSVPath

    foreach( $User in $Users ){
        $NewHome   = Join-Path -Path $NewHomeRoot -ChildPath $User.SamAccountName

        Robocopy.exe $User.homedirectory $NewHome /MIR /MOVE

        }
    Write-Host -ForegroundColor Green "All SD2 Leavers Home Folders Moved to Archive"

    #Delete Profile Folders
    $CSVPath = 'C:\LeaversExports\SD2_Leavers.csv'
    $Users = Import-Csv $CSVPath
    $samAccountName = $Users.SamAccountName
    $profilepathv6 = $Users.ProfilePath + ".V6"
    $profilepathv5 = $Users.ProfilePath + ".V5"

    foreach( $User in $Users ){
        if (Test-Path $profilepathv6){
        Write-Host -ForegroundColor Yellow "$profilepathv6 Path Found"
        Remove-Item ($profilepathv6)-Force -Confirm:$false
        Write-Host -ForegroundColor Green "$profilepathv6 - has been deleted"
        }
        Else{

        Write-Host -ForegroundColor Red ".V6 Path Not found - Skipped"

        }
        if (Test-Path $profilepathv5){
        Write-Host -ForegroundColor Yellow "$profilepathv5 Path Found"
        Remove-Item ($profilepathv5)-Force -Confirm:$false
        Write-Host -ForegroundColor Green "$profilepathv5 - has been deleted"
        }
            Else{

        Write-Host -ForegroundColor Red ".V5 Path Not found - Skipped"

        }
    }

    Write-Host -BackgroundColor Green -ForegroundColor Black "Profiles deleted"
    #Clean up working files
    #Remove-Item "C:\LeaversExports" -Force -recurse

    ################################################################################

    ################################################################################
    #Move users from SD3 to Leavers SD3
    $SD3 = "OU=SD3,OU=Students,DC=Contoso,DC=ac,DC=uk"
    $SD3Leavers = "OU=Leavers SD3,OU=Students,OU=Leavers,DC=Contoso,DC=ac,DC=uk"
    Get-ADUser -filter {Enabled -eq $false } -SearchBase $SD3 -properties name,samaccountname,DistinguishedName,homedirectory,ProfilePath |select SamAccountName,homedirectory,ProfilePath | export-csv C:\LeaversExports\SD3_Leavers.csv -nti
    Search-ADAccount –AccountDisabled –UsersOnly –SearchBase $SD3 | Move-ADObject –TargetPath $SD3Leavers
    Write-Host -ForegroundColor Green "SD3 - Disabled users Moved"


    # Remove User from All Group Memberships
    $Users = Get-ADUser -SearchBase $SD3Leavers -Filter *
    Get-ADGroup -Filter * | Remove-ADGroupMember -Members $users -Confirm:$False


    $users = Get-ADUser -SearchBase $SD3Leavers -Filter * 

    foreach($user in $users){
      $groups = Get-ADPrincipalGroupMembership $user.SamAccountName | Where-Object {$_.name -NotLike '*Domain*'}
      foreach($group in $groups){

        Remove-ADGroupMember -Identity $group -Members $user -erroraction silentlycontinue

      }
    }
    Write-Host -ForegroundColor Green "SD3 Leavers removed from all Groups"

    #Move SD3 Leavers Home Area to Archive
    $CSVPath      = 'C:\LeaversExports\SD3_Leavers.csv'
    $NewHomeRoot  = '\\FS2\K-R Leavers$\Leavers 18-19'
    #$NewHomeLocal = 'D:\Data\Users'

    $Users = Import-Csv $CSVPath

    foreach( $User in $Users ){
        $NewHome   = Join-Path -Path $NewHomeRoot -ChildPath $User.SamAccountName

        Robocopy.exe $User.homedirectory $NewHome /MIR /MOVE

        }
    Write-Host -ForegroundColor Green "All SD3 Leavers Home Folders Moved to Archive"

    #Delete Profile Folders
    $CSVPath = 'C:\LeaversExports\SD3_Leavers.csv'
    $Users = Import-Csv $CSVPath
    $samAccountName = $Users.SamAccountName
    $profilepathv6 = $Users.ProfilePath + ".V6"
    $profilepathv5 = $Users.ProfilePath + ".V5"

    foreach( $User in $Users ){
        if (Test-Path $profilepathv6){
        Write-Host -ForegroundColor Yellow "$profilepathv6 Path Found"
        Remove-Item ($profilepathv6)-Force -Confirm:$false
        Write-Host -ForegroundColor Green "$profilepathv6 - has been deleted"
        }
        Else{

        Write-Host -ForegroundColor Red ".V6 Path Not found - Skipped"

        }
        if (Test-Path $profilepathv5){
        Write-Host -ForegroundColor Yellow "$profilepathv5 Path Found"
        Remove-Item ($profilepathv5)-Force -Confirm:$false
        Write-Host -ForegroundColor Green "$profilepathv5 - has been deleted"
        }
            Else{

        Write-Host -ForegroundColor Red ".V5 Path Not found - Skipped"

        }
    }

    Write-Host -BackgroundColor Green -ForegroundColor Black "Profiles deleted"
    #Clean up working files
    #Remove-Item "C:\LeaversExports" -Force -recurse

    ################################################################################

    ################################################################################
    #Move users from SD4 to Leavers SD4
    $SD4 = "OU=SD4,OU=Students,DC=Contoso,DC=ac,DC=uk"
    $SD4Leavers = "OU=Leavers SD4,OU=Students,OU=Leavers,DC=Contoso,DC=ac,DC=uk"
    Get-ADUser -filter {Enabled -eq $false } -SearchBase $SD4 -properties name,samaccountname,DistinguishedName,homedirectory,ProfilePath |select SamAccountName,homedirectory,ProfilePath | export-csv C:\LeaversExports\SD4_Leavers.csv -nti
    Search-ADAccount –AccountDisabled –UsersOnly –SearchBase $SD4 | Move-ADObject –TargetPath $SD4Leavers
    Write-Host -ForegroundColor Green "SD4 - Disabled users Moved"


    # Remove User from All Group Memberships
    $Users = Get-ADUser -SearchBase $SD4Leavers -Filter *
    Get-ADGroup -Filter * | Remove-ADGroupMember -Members $users -Confirm:$False


    $users = Get-ADUser -SearchBase $SD4Leavers -Filter * 

    foreach($user in $users){
      $groups = Get-ADPrincipalGroupMembership $user.SamAccountName | Where-Object {$_.name -NotLike '*Domain*'}
      foreach($group in $groups){

        Remove-ADGroupMember -Identity $group -Members $user -erroraction silentlycontinue

      }
    }
    Write-Host -ForegroundColor Green "SD4 Leavers removed from all Groups"

    #Move SD4 Leavers Home Area to Archive
    $CSVPath      = 'C:\LeaversExports\SD4_Leavers.csv'
    $NewHomeRoot  = '\\FS2\S-Z Leavers$\Leavers 18-19'
    #$NewHomeLocal = 'D:\Data\Users'

    $Users = Import-Csv $CSVPath

    foreach( $User in $Users ){
        $NewHome   = Join-Path -Path $NewHomeRoot -ChildPath $User.SamAccountName

        Robocopy.exe $User.homedirectory $NewHome /MIR /MOVE

        }
    Write-Host -ForegroundColor Green "All SD4 Leavers Home Folders Moved to Archive"

    #Delete Profile Folders
    $CSVPath = 'C:\LeaversExports\SD4_Leavers.csv'
    $Users = Import-Csv $CSVPath
    $samAccountName = $Users.SamAccountName
    $profilepathv6 = $Users.ProfilePath + ".V6"
    $profilepathv5 = $Users.ProfilePath + ".V5"

    foreach( $User in $Users ){
        if (Test-Path $profilepathv6){
        Write-Host -ForegroundColor Yellow "$profilepathv6 Path Found"
        Remove-Item ($profilepathv6)-Force -Confirm:$false
        Write-Host -ForegroundColor Green "$profilepathv6 - has been deleted"
        }
        Else{

        Write-Host -ForegroundColor Red ".V6 Path Not found - Skipped"

        }
        if (Test-Path $profilepathv5){
        Write-Host -ForegroundColor Yellow "$profilepathv5 Path Found"
        Remove-Item ($profilepathv5)-Force -Confirm:$false
        Write-Host -ForegroundColor Green "$profilepathv5 - has been deleted"
        }
            Else{

        Write-Host -ForegroundColor Red ".V5 Path Not found - Skipped"

        }
    }

    Write-Host -BackgroundColor Green -ForegroundColor Black "Profiles deleted"
    #Clean up working files
    #Remove-Item "C:\LeaversExports" -Force -recurse

    ################################################################################

So I haven't been able to test this code just yet but could you take a look and let me know if what I have done looks correct based on your explanation of a Function.

function Cleanup-Shares
{
    Param(
    [Parameter(mandatory=$true)]
        [string]$ShareName,
        [String]$OU,
        [String]$LeaversOU,
        [String]$CSVPath,
        [String]$NewHomeRoot,
        [String]$LExport

    )

}

##########################################################################################################
                  #Disables Student accounts for leavers and moves them to the leavers OU
                  #Disables Parent Accounts, Strips groups, Moves to Parent Leavers OU

##########################################################################################################

#Import users to be disabled

#########################################################################################################
Import-Module ActiveDirectory
#Create working directory
#New-Item -ItemType directory "C:\LeaversExports"

Import-Csv "C:\Leavers.csv" | ForEach-Object {
$samAccountName = $_."samAccountName"
Get-ADUser -Identity $samAccountName | Disable-ADAccount
Write-host -ForegroundColor Green "$samAccountName Disabled"
}

###########################################################################################################
#Move users from SD1 to Leavers SD1
Get-ADUser -filter {Enabled -eq $false } -SearchBase $OU -properties name,samaccountname,DistinguishedName,homedirectory,ProfilePath |select SamAccountName,homedirectory,ProfilePath | export-csv C:\LeaversExports\$LExport.csv -nti
Search-ADAccount –AccountDisabled –UsersOnly –SearchBase $OU | Move-ADObject –TargetPath $LeaversOU
Write-Host -ForegroundColor Green "Disabled users Moved"


# Remove User from All Group Memberships
$Users = Get-ADUser -SearchBase $LeaversOU -Filter *
Get-ADGroup -Filter * | Remove-ADGroupMember -Members $users -Confirm:$False


$users = Get-ADUser -SearchBase $LeaversOU -Filter * 

foreach($user in $users){
  $groups = Get-ADPrincipalGroupMembership $user.SamAccountName | Where-Object {$_.name -NotLike '*Domain*'}
  foreach($group in $groups){

    Remove-ADGroupMember -Identity $group -Members $user -erroraction silentlycontinue

  }
}
Write-Host -ForegroundColor Green "$users removed from all Groups"

#Move Leavers Home Area to Archive

$Users = Import-Csv $CSVPath

foreach( $User in $Users ){
    $NewHome   = Join-Path -Path $NewHomeRoot -ChildPath $User.SamAccountName

    Robocopy.exe $User.homedirectory $NewHome /MIR /MOVE

    }
Write-Host -ForegroundColor Green "All Leavers Home Folders Moved to Archive"

#Delete Profile Folders
$Users = Import-Csv $CSVPath
$samAccountName = $Users.SamAccountName
$profilepathv6 = $Users.ProfilePath + ".V6"
$profilepathv5 = $Users.ProfilePath + ".V5"

foreach( $User in $Users ){
    if (Test-Path $profilepathv6){
    Write-Host -ForegroundColor Yellow "$profilepathv6 Path Found"
    Remove-Item ($profilepathv6)-Force -Confirm:$false
    Write-Host -ForegroundColor Green "$profilepathv6 - has been deleted"
    }
    Else{

    Write-Host -ForegroundColor Red ".V6 Path Not found - Skipped"

    }
    if (Test-Path $profilepathv5){
    Write-Host -ForegroundColor Yellow "$profilepathv5 Path Found"
    Remove-Item ($profilepathv5)-Force -Confirm:$false
    Write-Host -ForegroundColor Green "$profilepathv5 - has been deleted"
    }
        Else{

    Write-Host -ForegroundColor Red ".V5 Path Not found - Skipped"

    }
    Write-Host -BackgroundColor Green -ForegroundColor Black "Profiles deleted"
}

Cleanup-Shares -OU "OU=SD1,OU=Students,DC=Contoso,DC=ac,DC=uk" -LeaversOU "OU=Leavers SD1,OU=Students,OU=Leavers,DC=contoso,DC=ac,DC=uk" -CSVPath "C:\LeaversExports\SD1_Leavers.csv" -NewHomeRoot "\\FS1\A-D Leavers$\Leavers 18-19$" -LExport "SD1"
Cleanup-Shares -OU "OU=SD2,OU=Students,DC=Contoso,DC=ac,DC=uk" -LeaversOU "OU=Leavers SD2,OU=Students,OU=Leavers,DC=contoso,DC=ac,DC=uk" -CSVPath "C:\LeaversExports\SD2_Leavers.csv" -NewHomeRoot "\\FS1\E-J Leavers$\Leavers 18-19" -LExport "SD2"
Cleanup-Shares -OU "OU=SD3,OU=Students,DC=Contoso,DC=ac,DC=uk" -LeaversOU "OU=Leavers SD3,OU=Students,OU=Leavers,DC=contoso,DC=ac,DC=uk" -CSVPath "C:\LeaversExports\SD3_Leavers.csv" -NewHomeRoot "\\FS2\K-R Leavers$\Leavers 18-19" -LExport "SD3"
Cleanup-Shares -OU "OU=SD4,OU=Students,DC=Contoso,DC=ac,DC=uk" -LeaversOU "OU=Leavers SD4,OU=Students,OU=Leavers,DC=contoso,DC=ac,DC=uk" -CSVPath "C:\LeaversExports\SD4_Leavers.csv" -NewHomeRoot "\\FS2\S-Z Leavers$\Leavers 18-19" -LExport "SD4"
\$\endgroup\$
  • \$\begingroup\$ at this point $profilepathv6 = $Users.ProfilePath + ".V6" the $Users variable otta contain a COLLECTION. that means your .ProfilePath will also be a collection. ///// i don't see how that could possibly work ... \$\endgroup\$ – Lee_Dailey Oct 31 '18 at 12:20
  • \$\begingroup\$ What is a COLLECTION? I have not heard of one of them before, also thank you peter on the suggestion, i have posted at code review now also. \$\endgroup\$ – Karl Hardy Oct 31 '18 at 12:52
  • \$\begingroup\$ Collection \$\endgroup\$ – Theo Oct 31 '18 at 13:22
  • \$\begingroup\$ As we all want to make our code more efficient or improve it in one way or another, try to write a title that summarizes what your code does, not what you want to get out of a review. Please see How to get the best value out of Code Review - Asking Questions for guidance on writing good question titles. \$\endgroup\$ – BCdotWEB Jan 7 '19 at 14:50
2
\$\begingroup\$

Two solutions comes in my mind for shorting the script.

Either use a function which contains the main code, and then on the end you can call the function with the necessary variables. In this with the different drive letters.

The other way is to use a Foreach cycle in a list, and every foreach item would be one of your shares like:

$Sharelist = @("A-D Leavers$","E-J Leavers$","K-R Leavers$","S-Z Leavers$")

I would use the function.

function Cleanup-Shares
{
    Param(
    [Parameter(mandatory=$true)]
        [string]$ShareName,
        [String]$OrganizationUnit
    )
#Here comes the main section    

}
Cleanup-Shares -ShareName "A-D" -OrganizationUnit "OU=SD1,OU=Students,DC=Contoso,DC=ac,DC=uk"
Cleanup-Shares -ShareName "E-J" -OrganizationUnit "OU=SD2,OU=Students,DC=Contoso,DC=ac,DC=uk"
Cleanup-Shares -ShareName "K-R" -OrganizationUnit "OU=SD3,OU=Students,DC=Contoso,DC=ac,DC=uk"
Cleanup-Shares -ShareName "S-Z" -OrganizationUnit "OU=SD4,OU=Students,DC=Contoso,DC=ac,DC=uk"

Hope this helps.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Hi, still pretty new to powershell and coding in general, am i right in thinking that what you are doing is putting all my code into that function which allows me to create the variables for each of the shares, and then at the end of the code i just call the function with each variable? \$\endgroup\$ – Karl Hardy Oct 31 '18 at 15:31
  • \$\begingroup\$ Yes, you see it right. So your code will be much shorter, and easier to overview. \$\endgroup\$ – Creater Nov 5 '18 at 8:28
  • \$\begingroup\$ You create the variable for the ShareNames and OrganizationUnit once, and than just give the value of this variables by calling the function with the necessary properties, like in the last lines of the code I've written. \$\endgroup\$ – Creater Nov 5 '18 at 8:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.