Restore.psm1
function Restore-Terminal { [CmdletBinding()]param() $Restore = Get-ChildItem "$Env:APPDATA\restore.*.clixml" | Where-Object { $process = Get-Process -Id ($_.Name.Split('.')[1]) -ErrorAction SilentlyContinue -not $_.FullName.Contains($Pid.ToString()) -and $null -eq $process } | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1 if (-not $Restore) { return } $Terminal = Import-Clixml -Path $Restore.FullName Write-Verbose "Restoring from checkpoint: $($Restore.FullName)" Write-Verbose "Restoring terminal location: $($Terminal.Location)" Remove-Item $Restore.FullName Set-Location $Terminal.Location $Terminal.Variables | ForEach-Object { try { Set-Variable -Name $_.Name -Value $_.Value -ErrorAction SilentlyContinue -Scope "Global" } catch {} } $Terminal.Modules | ForEach-Object { Import-Module $_.Path -Scope "Global" } } function Clear-TerminalCheckpoint { $Checkpoints = Get-ChildItem "$Env:APPDATA\restore.*.clixml" if ($Checkpoints.Length -gt 10) { $Checkpoints | Sort-Object -Property LastWriteTime -Descending | Select-Object -Skip 10 | Remove-Item } } function Checkpoint-Terminal { $state = @{ Location = (Get-Location).ToString() Variables = Get-Variable -Scope "Global" | ForEach-Object { [PSCustomObject]@{ Name = $_.Name; Value = $_.Value } } Modules = Get-Module | ForEach-Object { [PSCustomObject]@{ Name = $_.Name; Path = $_.Path } } } Start-Job -ScriptBlock { $args[0] | Export-Clixml -Path "$Env:AppData\restore.$pid.clixml" } -ArgumentList $state } $Host.Runspace.add_AvailabilityChanged({Checkpoint-Terminal}) Clear-TerminalCheckpoint |