Function CreateShadow($disk)
{
    # e.g. c: -> c:\
    $disk = $disk[0] + ':\';

    $shadowObj = (gwmi -List Win32_ShadowCopy).Create($disk, "ClientAccessible")
    $currentShadow = gwmi Win32_ShadowCopy | ? { $_.ID -eq $shadowObj.ShadowID }
    $shadowID = $currentShadow.ID
    $name  = $currentShadow.DeviceObject + "\"
    $dummy = cmd /c "mklink /d .\$shadowID $name"
    Write-Host $dummy
    return $shadowID
}

Function DropShadow($shadowID)
{
    $dummy = cmd /c "rmdir .\$shadowID"
    Write-Host $dummy
    $currentShadow = gwmi Win32_ShadowCopy | ? { $_.ID -eq $shadowID }
    $currentShadow.Delete()
}

Function PerformBackup($shadowPath, $bakRoot)
{
    if ($shadowPath -like '%\')
    {
        $shadowPath = $shadowPath.SubString(0, $shadowPath.Length - 1)
    }

    if ($bakPath -like '%\')
    {
        $bakPath = $bakPath.SubString(0, $bakPath.Length - 1)
    }

    $tmpFile = "$PWD\tmpFileList.txt"

    # if script was incorrectly finished
    if (Test-Path $tmpFile)
    {
        Remove-Item $tmpFile
    }
    Get-ChildItem -Recurse "$($shadowPath)\Windows\System32\Config" -Force -ErrorAction Continue | % { $_.FullName.Remove(0, $shadowPath.Length + 1) | Out-File -FilePath $tmpFile -Encoding ascii -Append }

    Get-ChildItem "$($shadowPath)\Users\" -Directory | % { Get-ChildItem -File -Force "$($_.FullName)\ntuser.*" -ErrorAction SilentlyContinue | % { $_.FullName.Remove(0, $shadowPath.Length + 1) | Out-File -FilePath $tmpFile -Encoding ascii -Append } }

    $archName = Get-Date -Format 'yyyyMMdd'

    # if file exists, using _1, _2, ...
    $archPath = $bakRoot + '\' + $archName;
    $iterator = 1;
    while (Test-Path "$archPath.7z")
    {
        $archPath = $bakRoot + '\' + $archName + '_' + $iterator;
        $iterator++;
    }

    $curPWD = $PWD
    cd $shadowPath
    cmd /c "$($curPWD)\7z.exe a -m0=LZMA2 $archPath.7z @$tmpFile"
    cd $curPWD
    Remove-Item $tmpFile
}

Function RemoveOldBackups($bakPath)
{
    dir $bakPath | ? { $_.CreationTime -le $(Get-Date).AddDays(-30) } | Remove-Item
}


$backupPath = 'T:\reg_back_period'
$systemDisk = 'C:\'

Echo $pwd

Echo 'Creating Shadow'
$shadow = CreateShadow $systemDisk
Echo "Shadow ID: $shadow"
Echo 'Performing Backup'
PerformBackup -shadowPath "$pwd\$shadow" -bakRoot $backupPath
Echo 'Dropping shadow'
DropShadow $shadow
Echo 'Cleaning Backups'
RemoveOldBackups $backupPath