Home > Software design >  Copy from Specific Folder with Multiple Folders
Copy from Specific Folder with Multiple Folders

Time:08-24

I am creating a backup and restore tool with powershell script and I am trying to make it so that when restoring, the script picks the last folder created and restores from that directory structure. Basically I am having the script start with making a backup directory with a date/time stamp like so:

    $CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
    $CurrentDomainName = $CurrentUser.split("\")[0]
    $CurrentUserName = $CurrentUser.split("\")[1]
    $folderdate = Get-Date -f MMddyyyy_Hm
    $homedir = Get-Aduser $CurrentUserName -prop HomeDirectory | select -ExpandProperty 
    HomeDirectory
    New-Item $homedir -Name "TXBackup\$folderdate" -ItemType Directory

    $cbookmarks = "$env:userprofile\Appdata\Local\Google\Chrome\User Data\Default\Bookmarks"
    md $homedir\TXBackup\$folderdate\Chrome
    Copy-Item $cbookmarks "$homedir\TXBackup\$folderdate\Chrome" -Recurse

Backup Folder Structure

Basically everytime someone runs the backup tool it will create a subfolder under the Backup directory with the date/time name to track the latest one. The problem comes when I want to restore from the last one create I can no longer use a $folderdate variable since it will pull the whatever the time is while the tool is being run. Here is the code without taking into account what the last folder is. I tried using sort but that doesn't appear to give me a clear path to select the last one created or I just am such a noob I didn't use it right :(

   ##Restoring Files from Backup
    $CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
    $CurrentDomainName = $CurrentUser.split("\")[0]
    $CurrentUserName = $CurrentUser.split("\")[1]
    $homedir = get-aduser $CurrentUserName -prop HomeDirectory | select -ExpandProperty HomeDirectory
    
    ##Restoring Chrome Bookmarks
    Sort-Object -Property LastWriteTime |
        Select-Object -Last 1
    $rbookmarks = "$homedir\TXBackup\$folderdate\Chrome\Bookmarks"
    Copy-Item $rbookmarks "C:\Test\"

I know I didn't use that correctly but any direction would be awesome for this newbie :)

CodePudding user response:

You can use Sort-Object with a script block and use [DateTime] methods to parse the date from the folder name, using the same format string you used to create them.

# Sort directory names descending
Get-ChildItem -Directory | Sort-Object -Desc { 

   # Try to parse the long format first
   $dt = [DateTime]::new( 0 ) 
   if( [DateTime]::TryParseExact( $_.Name, 'MMddyyyy_HHmm', [CultureInfo]::InvariantCulture, [Globalization.DateTimeStyles]::none, [ref] $dt ) ) {
       return $dt 
   }
   # Fallback to short format
   [DateTime]::ParseExact( $_.Name, 'MMddyyyy', [CultureInfo]::InvariantCulture )

} | Select-Object -First 1 | ForEach-Object Name

Note: I've changed the time format from Hm to HHmm, because Hm would cause a parsing ambiguity, e. g. 01:46 would be formatted as 146, but parsed as 14:06.

Also I would move the year to the beginning, e. g. 20220821_1406, so you could simply sort by name, without having to use a script block. But that is not a problem, just an (in)convenience and you might have a reason to put the year after the day.

Given these folders:

08212022
08222022
08222022_1406
08222022_1322
08222022_1324
08222022_1325
08222022_1343

The code above produces the following output:

08222022_1406

To confirm the ordering is correct, I've removed the Select-Object call:

08222022_1406
08222022_1343
08222022_1325
08222022_1324
08222022_1322
08222022
08212022

Note that the ordering is descending (-Desc), so Select-Object -First 1 can be used to more effectively select the latest folder.

  • Related