我不小心從命令列洗掉了幾個Powershell腳本,恢復工具也沒有成功恢復它們。碰巧的是,兩個最重要的腳本在洗掉時正在運行(在正常的 Powershell 提示符而不是 ISE 中),并且它們仍在正常運行。是否可以從記憶體中恢復這兩個腳本?
uj5u.com熱心網友回復:
PowerShell每次從腳本檔案編譯腳本塊時都會快取結果,然后按腳本名稱/路徑和內容索引編譯的塊 - 因此我們可以提取已經在給定主機應用程式中運行的原始腳本反射:
function Get-ScriptBlockCache {
# Internal variable name changed in PowerShell core, take into account
$fieldName = '_cachedScripts'
if($PSVersionTable.PSVersion.Major -ge 6){
$fieldName = 's_cachedScripts'
}
# Obtain type metadata for the field we want to extract values from
$cachedScriptsMemberInfo = [scriptblock].GetMember($fieldName, 'Static,NonPublic')[0]
# We're only interested in the keys, since they contain the original script text
return @($cachedScriptsMemberInfo.GetValue($null).Keys) |Select @{Name='Path';Expression='Item1'},@{Name='ScriptSourceCode';Expression='Item2'}
}
現在你可以這樣做:
Get-ScriptBlockCache |Where-Object Path -like "*nameOfDeletedScript.ps1" |ForEach-Object ScriptSourceCode
如果您沒有即時訪問權限怎么辦?
如果行程在無人參與的情況下運行(例如,作為計劃任務或使用-File和運行-NoExit),您可以使用 PowerShell 令人驚嘆的除錯工具在目標行程中開辟輔助運行空間并從那里運行快取恢復:
Enter-PSHostProcess -Id <targetProcessId>
# Once you're dropped into the target process, define the `Get-ScriptBlockCache` function and execute it
如果行程已經退出怎么辦?
如果行程不再運行,那么快取也會丟失- 但還有另一種選擇:ScriptBlock 日志!
如果機器配置為啟用了強制腳本塊日志記錄,您還可以從事件日志中獲取 PowerShell 已決議的任何腳本或腳本塊(假設日志條目尚未被覆寫):
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational';Id=4104} |Select TimeCreated,@{Name='SourceCode';Expression={$_.Properties[2].Value}}
This won't show process id or script path/name, but if you know which time it executed and have a rough idea of the scripts contents, you should be able to glean it from those logs :)
Note: The script block cache extraction trick only works in ISE if you invoked the script from disk, eg & path\to\script.ps1 - scripts opened in the editor pane and executed directly within ISE will not have been cached in this fashion.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/454132.html
下一篇:如何將西里爾字母轉換為utf16
