Script For Moving RDS Profile Folders

Not so long ago, I upgraded an RDS farm from Windows Server 2012 R2 to Windows Server 2016, where the main task was to reconfigure the roaming profile folders due to the name change from v2 to v6. After the transfer, the total number of folders was over 6000, they already took up decent disk space. There was an idea to remove unnecessary ones according to the criteria,
  1. Active Directory user account disabled more than 60 days ago.
  2. Move a folder over the network to an archive server.
  3. Move no more than 25 folders per day, so that in case of something there is not a large number of applications.
  4. Keep all rights to folders and subfolders.
  5. Place the script in scheduled tasks and run as scheduled,
    1. #Requires - Modules ActiveDirectory  
    2. #Requires - RunAsAdministrator  
    3. function Date {  
    4.     Get - Date - format "HH: mm: ss dd.MM.yyyy"  
    5. }  
    6. # Specify the folder  
    7. for creating logs and the format of the file name,  
    8.     if it is not there, then create it  
    9. $ log_folder = "$ PSScriptRoot \ Logs \" + $ ($ MyInvocation.MyCommand.Name -replace (".ps1 ", "  
    10. "))    
    11. $ log = "$ log_folder \ $ (Get-Date -Format"  
    12. yyyy_MM_dd_HH_mm_ss "). txt"  
    13. if (!(Test - Path $ log_folder - PathType Container - ErrorAction SilentlyContinue)) {  
    14.     New - Item $ log_folder - ItemType D - Force | Out - Null  
    15. }  
    16. "$ (Date) Start Processing" | Tee - Object $ log - Append  
    17. # # # Maximum we move 25 folders  
    18. $ max_folders_to_move = 25  
    19. # Define variables where the sources of the source folders and their final location are specified  
    20. $ source_ts_profiles_folder = "\\ Dfs07.root.pyatilistnik.org \ m $ \ Share \ tsProfiles_TermNew"  
    21. $ dest_ts_profiles_folder = "\\ SBU03.root.pyatilistnik.org \ D $ \ share \ Unused Files \ tsProfiles_TermNew"  
    22. # Define variables where the sources of the source folders and their final location are specified  
    23. $ source_home_folder1 = "\\ Dfs05.root.pyatilistnik.org \ S $ \ Share \ home1"  
    24. $ source_home_folder2 = "\\ Dfs05.root.pyatilistnik.org \ S $ \ Share \ home2"  
    25. $ dest_home_folder = "\\ S03.root.pyatilistnik.org \ D $ \ share \ Unused Files \ home"  
    26. # Specifies an Active Directory lookup that specifies a global catalog server  
    27. $ DCs = @ {}  
    28. foreach($ domain in (Get - ADForest).Domains) {  
    29.     $ DC = ""  
    30.     $ DC = (Get - ADDomain $ domain).ReplicaDirectoryServers | select - First 1  
    31.     $ DCs.Add($ domain, $ DC)  
    32. }  
    33. $ GC = $ DCs.  
    34. "Root.pyatilistnik.org" + ": 3268"  
    35. "$ (Date) Will use` "  
    36. $ GC`" as Global Catalog Server "| Tee-Object $ log -Append    
    37. ### Declaring the variable $ i for the first time    
    38. $ i = 1    
    39. foreach ($ folder in (Get-ChildItem $ source_ts_profiles_folder -Directory)) # | select -First 10    
    40. {    
    41. if ($ i -gt $ max_folders_to_move) {Continue}    
    42. $ username = $ domain = $ domain_long = $ user = $ server = $ lastLogonTimeStamp = $ null    
    43. # Divide the folder name of the domain \ username.v6 format    
    44. $ domain = $ ($ folder.Name -split "\.") [- 2]    
    45. $ v = $ ($ folder.Name -split "\.") [- 1]    
    46. $ domain_long = $ DCs.Keys | ? {$ _ -like "$ domain *"}    
    47. $ username = $ folder.Name -replace (". $ domain. $ v""")    
    48. if (! $ domain_long)    
    49. {    
    50. "$ (Date) Unable to identify domain. Please check folder`  
    51. "$ ($ folder.Name)` "  
    52. " | Tee-Object $ log -Append    
    53. Continue  
    54. }  
    55. $ server = $ DCs.$ domain_long  
    56. # "$ (Date) Trying to find user` "  
    57. $ username`" in domain $ domain / $ domain_long using DC $ server "| Tee-Object $ log -Append    
    58. try {    
    59. $ user = Get-ADUser $ username -Properties lastLogonTimeStamp -Server $ server -ErrorAction Stop    
    60. }    
    61. catch {    
    62. "$ (Date) $ ($ _. Exception.message)" | Tee-Object $ log -Append    
    63. }    
    64. $ lastLogonTimeStamp_diff = (New-TimeSpan -Start $ ([datetime] :: FromFileTime ($ user.lastLogonTimeStamp)) -End $ (Get-Date)). Days    
    65. # It is indicated that we are looking for users with the status off for at least 60 days    
    66. if ($ user.Enabled -eq $ false -and $ lastLogonTimeStamp_diff -gt 60)    
    67. {    
    68. "$ (Date) User`  
    69. "$ username`"  
    70. Enabled status is $($ user.Enabled), lastLogonTimeStamp diff days: $ lastLogonTimeStamp_diff "| Tee-Object $ log -Append    
    71. "$ (Date) Going to move folder $ i / $ max_folders_to_move` "  
    72. $($ folder.Fullname)` "to`  
    73. "$ dest_ts_profiles_folder`"  
    74. "| Tee-Object $ log -Append    
    75. # Calling the utility of the robocopy utility with the necessary keys  
    76. $ log_robocopy = "$ log_folder \ robocopy_" + (Get - Date - Format "yyyy_MM_dd_HH_mm_ss") + ".log" & robocopy `" $ ($ folder.Fullname) `  
    77. " `"  
    78. $ dest_ts_profiles_folder\ $($ folder.Name) `" / NJH / MOVE / S / B / UNILOG: $ log_robocopy # / L    
    79. $ i ++    
    80. }    
    81. }    
    82. ###    
    83. $ i = 1    
    84. foreach ($ folder in (Get-ChildItem $ source_home_folder1, $ source_home_folder2 -Directory)) # | select -First 10    
    85. {    
    86. if ($ i -gt $ max_folders_to_move) {Continue}    
    87. $ username = $ user = $ users_found = $ lastLogonTimeStamp = $ null    
    88. $ username = $ folder.Name # -replace (". $ domain. $ v""")    
    89. # "$ (Date) Trying to find user`  
    90. "$ username`" in thw whole AD forest "| Tee-Object $ log -Append    
    91. try {  
    92.     $ user = Get - ADUser $ username - Properties lastLogonTimeStamp - Server $ GC - ErrorAction Stop  
    93. catch {  
    94.     "$ (Date) $ ($ _. Exception.message)" | Tee - Object $ log - Append  
    95. }  
    96. $ users_found = ($ user | Measure - Object).Count  
    97. # "$ (Date) Found users: $ users_found" | Tee - Object $ log - Append  
    98. if ($ users_found - ne 1) {  
    99.     "$ (Date) Need to check AD for folder` "  
    100.     $($ folder.FullName)` '"| Tee-Object $ log -Append    
    101. Continue    
    102. }    
    103. $ lastLogonTimeStamp_diff = (New-TimeSpan -Start $ ([datetime] :: FromFileTime ($ user.lastLogonTimeStamp)) -End $ (Get-Date)). Days    
    104. # It is indicated that we are looking for users with the status off for at least 60 days    
    105. if ($ user.Enabled -eq $ false -and $ lastLogonTimeStamp_diff -gt 60)    
    106. {    
    107. "$ (Date) User`  
    108.     "$ username`"  
    109.     Enabled status is $($ user.Enabled), lastLogonTimeStamp diff days: $ lastLogonTimeStamp_diff "| Tee-Object $ log -Append    
    110.     "$ (Date) Going to move folder $ i / $ max_folders_to_move` "  
    111.     $($ folder.Fullname)` "to`  
    112.     "$ dest_home_folder`"  
    113.     "| Tee-Object $ log -Append    
    114.     # Calling the utility of the robocopy utility with the necessary keys  
    115.     $ log_robocopy = "$ log_folder \ robocopy_" + (Get - Date - Format "yyyy_MM_dd_HH_mm_ss") + ".log" & robocopy `" $ ($ folder.Fullname) `  
    116.     " `"  
    117.     $ dest_home_folder\ $($ folder.Name) `" / NJH / MOVE / S / B / UNILOG: $ log_robocopy    
Next Recommended Reading Powershell Script to Monitor Disk Space