function Get-UserProfileBackup($Computer) { <# .SYNOPSIS Backs up a user profile. .DESCRIPTION Takes a input of hostname and user and will make a copy of the user profile and the Microsoft Roaming Folder and back it up on the share drive. #> #Charles Beddow maintains the UserProfileBackup #The folders that this back up file grabs $FoldersToCopy = @( 'Desktop' 'Downloads' 'Favorites' 'Documents' 'Pictures' 'Videos' 'AppData\Local\Google\Chrome\User Data\Default\Bookmarks' 'AppData\Roaming\Microsoft' 'Sticky Notes' ) if($Computer -eq $null){ $Computer = Read-Host -Prompt 'Enter computer name: ' } $ConfirmUser = $null #Collects the most recent users for options to backup if($Computer -eq $env:COMPUTERNAME) { Import-Module "\\basagh\team\shsisdesktopsolutions\Powershell\Get-PC\Modules\PCLocal\PCLocal.psm1" #Below are commands for the local PC when using "get-pc" by itself $lastUser = Get-PCLastUserLocal } else { $lastUser = Invoke-Command -ComputerName $Computer -SessionOption (New-PSSessionOption -NoMachineProfile) -ScriptBlock { Get-ChildItem -Path C:\Users -Directory -Force -Exclude Public,Default,'Default User','All Users' | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 3 -ExpandProperty Name } if($lastUser -eq $null){ Write-warning "PC unreachable or no profiles to back up" return } } Write-Host "Latest Users: $lastUser" #Asks user to pick which profile to backup while( $ConfirmUser -eq $null ){ $User = Read-Host -Prompt 'Choose user to backup' if( -not ( Test-Path -Path "\\$Computer\c$\Users\$User" -PathType Container ) ){ Write-Warning "$User could not be found on $Computer. Please enter another user profile." continue } else { $testPath = Resolve-Path -Path "\\$Computer\c$\Users\$User\Desktop" if (-not $testPath ){ Write-Warning "Unable to access profile" Write-Warning "Please try running script as Admin" break } } <# Write-Host "Scanning user profile..." $profileSize = scan-dir "\\$Computer\c$\Users\$User" $sizeout = "{1} profile is {0:n3}GB" -f $profileSize,$user Write-Host $sizeout #> $ConfirmUser = Read-Host -Prompt "Copy profile? (y/n) or Restore profile (r)" if($ConfirmUser -eq 'n'){ $ConfirmUser = Read-Host -Prompt "Choose another user? (y/n)" if($ConfirmUser -eq 'y'){ $ConfirmUser = $null continue } } } if($ConfirmUser -eq 'n'){ Write-Host "User backup canceled" } #Backup Locations $backupLocations = @() $obj = New-Object PSObject -Property @{ Site='GSRMC' Path="\\SHSCMGSRMC\ProfileBackup"} $backupLocations += $obj $obj = New-Object PSObject -Property @{ Site='SAGH' Path="\\SHSCMSAGH\ProfileBackup"} $backupLocations += $obj $obj = New-Object PSObject -Property @{ Site='SNLH' Path="\\SHSCMSNLH\ProfileBackup"} $backupLocations += $obj $obj= New-Object PSObject -Property @{ Site='LCH' Path="\\shscmslch\ProfileBackup"} $backupLocations += $obj $obj = New-Object PSObject -Property @{ Site='Walnut' Path="\\SHSCMWN\ProfileBackup"} $backupLocations += $obj $obj = New-Object PSObject -Property @{ Site='Sam Square' Path="\\SHSCMAV\ProfileBackup"} $backupLocations += $obj $obj = New-Object PSObject -Property @{ Site='HP' Path="\\SHSCM01\ProfileBackup"} $backupLocations += $obj $obj = New-Object PSObject -Property @{ Site='SPCH' Path="\\SHSCMSPCH\ProfileBackup"} $backupLocations += $obj $obj = New-Object PSObject -Property @{ Site='Old Team Share' Path="\\basagh\team\SHSISDesktopSolutions\General Shared Items\User Profile Backup"} $backupLocations += $obj $Date = Get-Date -Format "MM-dd" $DestinationFileName = "$Computer-$User-$Date" $SourceRoot = "\\$Computer\c$\Users\$User" $BackupDestination = "\\SHSCMGSRMC\ProfileBackup" $Destination = "\\SHSCMGSRMC\ProfileBackup\$DestinationFileName" $CopiedUserDesktop = Join-Path -Path $Destination -ChildPath "Desktop" #region BACKUP if($ConfirmUser -eq 'y'){ #Chooses Site to Backup the profile to Write-Host "Choose Site to backup" for($i=0;$i -lt 8; $i++){ $out = "[{0}]: {1}" -f $i, $backupLocations[$i].Site Write-Host $out } [int]$site = Read-Host "Site" if(!(($site -ge 0 ) -and ($site -lt 8))){ Write-Warning "Invalid input please restart script" return } $BackupDestination = $backupLocations[$site].Path $Destination = "$BackupDestination\$DestinationFileName" #Creates a backup directory named "ComputerName-User-TodaysDate" New-Item -Path $Destination -ItemType Directory | Write-Verbose if($User -eq "Public"){ $FoldersToCopy = @('Desktop') } #Creates a log file New-Item -Path $Destination\backuplog.txt -Force | Write-Verbose $log = Join-Path -Path $Destination -ChildPath backuplog.txt Write-Host "Copying profile to $Destination" foreach( $Folder in $FoldersToCopy ){ $Source = Join-Path -Path $SourceRoot -ChildPath $Folder Write-Host "Copying $Folder" if( $Folder -eq 'Sticky Notes'){ $Source = Join-Path -Path $SourceRoot -ChildPath 'AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState' } #Checks if folder paths are available if( -not ( Test-Path -Path $Source ) ){ Write-Warning "Could not find path`t$Source" continue } if( -not ( Test-Path -Path $Destination -PathType Container ) ){ Write-Warning "Could not find path`t$Destination" continue } if($Folder -eq 'AppData\Roaming\Microsoft'){ #If it's time to copy AppData folder it changes the copy destination to build the proper directory tree $Destination = Join-Path -Path $Destination -ChildPath 'AppData\Roaming\Microsoft' Copy-Item -Path (Get-Item -Path "$Source\*" -Exclude ('Teams')).FullName -Destination $Destination -Recurse -Force -PassThru | Out-File $log -Append Write-Host 'complete' continue } if ($Folder -eq 'Sticky Notes'){ $Destination = Join-Path -Path "$BackupDestination\$DestinationFileName" -ChildPath 'Sticky Notes' } Copy-Item $Source -Destination $Destination -Recurse -PassThru | Out-File $log -Append Write-Host "complete" } #Cleans up Citrix Shortcuts Write-Host "Removing Citrix Shortcuts from backup" $Shortcuts = Get-ChildItem -Path $CopiedUserDesktop -Filter *.lnk foreach($Shortcut in $Shortcuts){ $sh = New-Object -ComObject WScript.Shell if($sh.CreateShortcut($Shortcut.FullName).TargetPath -eq 'C:\Program Files (x86)\Citrix\ICA Client\SelfServicePlugin\SelfService.exe') { Remove-Item $Shortcut.FullName } } Write-Host "Complete" } #endregion #region RESTORE if($ConfirmUser -eq 'r'){ $backups = @() foreach($b in $backupLocations) { $paths = @() $paths += Get-ChildItem -Path $b.Path -Name -Filter "*$User*" foreach($p in $paths){ $obj = New-Object PSObject -Property @{ File = $p Location = $b.Path } $backups += $obj } } if($null -eq $backups[0]){ Write-Warning "no backups available for this user" return } else{ Write-Host "These backups are available for this user:" } if($backups -is [array]) { $i = 0 foreach ($backup in $backups){ $out = $backup.File Write-Host "[$i] $out" $i++ } $FileToRestoreIndex = Read-Host -Prompt "Please type which directory you'd like to restore" $FileToRestore = $backups[$FileToRestoreIndex].File $BackupDestination = $backups[$FileToRestoreIndex].Location } else{ $out = $backups.File Write-Host "[0] $out" $FileToRestoreIndex = Read-Host -Prompt "Please confirm which directory you'd like to restore" if($FileToRestoreIndex -eq 0){ $FileToRestore = $backups.File $BackupDestination = $backups.Location } } Write-Host "Restoring $FileToRestore" Write-Host "--------------------" $FullRestorationSource = Join-Path -Path $BackupDestination -ChildPath $FileToRestore Write-Verbose $FullRestorationSource if( -not ( Test-Path -Path $FullRestorationSource -PathType Container ) ){ Write-Warning "The backup you have chosen does not exist" break } if($User -eq "Public"){ $FoldersToCopy = @('Desktop') } foreach( $Folder in $FoldersToCopy ){ #Special Case for AppData if($Folder -eq 'AppData\Roaming\Microsoft'){ $Folder = 'AppData' } $CurrentRestoreFolder = Join-Path -Path $FullRestorationSource -ChildPath $Folder #Special Case for Google Bookmarks if($Folder -eq 'AppData\Local\Google\Chrome\User Data\Default\Bookmarks'){ Write-Host "Restoring Chrome Bookmarks" if( -not ( Test-Path -Path $FullRestorationSource\Bookmarks)){ Write-Host "No Chrome Bookmarks backup" continue } if( -not ( Test-Path -Path "$SourceRoot\AppData\Local\Google\Chrome")){ Write-Warning "Restoring Chrome bookmarks but Chrome is not installed on this machine" } if( -not ( Test-Path -Path "$SourceRoot\AppData\Local\Google\Chrome\User Data\Default")){ New-Item "$SourceRoot\AppData\Local\Google\Chrome\User Data\Default" -ItemType Container | Write-Verbose } Copy-Item $FullRestorationSource\Bookmarks -Destination "$SourceRoot\AppData\Local\Google\Chrome\User Data\Default\Bookmarks" -Force Write-Host "complete" continue } #Special Case for Sticky Notes if($Folder -eq 'Sticky Notes'){ continue } Write-Host "Restoring $Folder" #Checks if folder paths are available if( -not ( Test-Path -Path $CurrentRestoreFolder -PathType Container ) ){ Write-Warning "Could not find path`t$Source" continue } if( -not ( Test-Path -Path $SourceRoot -PathType Container ) ){ Write-Warning "Could not find path`t$Destination" continue } Copy-Item $CurrentRestoreFolder -Destination $SourceRoot -Recurse -Force Write-Host "complete" } } #endregion }#End Function #Helper Function function scan-dir($Path) { if ( (Test-Path $Path) -and (Get-Item $Path).PSIsContainer ){ $DirectorySize = (Get-ChildItem -Path $path -File -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1GB Return $DirectorySize } }