[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fEatUoqfh8o4OB9mefBBGsApcUG5J3gOVEjvW7fPB7s8":3},{"id":4,"question":5,"answer":6,"answerHtml":7,"slug":8,"keywords":9,"article":10,"status":34,"aiModel":39,"aiConfidence":39,"updatedAt":51,"createdAt":51,"_status":50},747,"How can an attacker obtain PowerShell command history from a background process that cannot receive keyboard input?","If the PowerShell process is running a script in the background (e.g., `PowerShell -ep bypass -f 1.ps1`), the attacker can read the process's command-line arguments to extract useful information. Open-source tools exist to enumerate and read these arguments, as sensitive data like credentials may be embedded directly in the script's parameters.","\u003Cp>If the PowerShell process is running a script in the background (e.g., `PowerShell -ep bypass -f 1.ps1`), the attacker can read the process&#39;s command-line arguments to extract useful information. Open-source tools exist to enumerate and read these arguments, as sensitive data like credentials may be embedded directly in the script&#39;s parameters.\u003C\u002Fp>\u003Cp>\u003Ca href=\"\u002Fnews\u002Fpenetration-techniques-obtaining-powershell-command-history\">Read the related One Day Sec article\u003C\u002Fa>\u003C\u002Fp>","how-can-an-attacker-obtain-powershell-command-history-from-a-background-process--1777482137556","background PowerShell process, command-line arguments, credential extraction, penetration testing",{"id":11,"title":12,"slug":13,"description":14,"content":15,"contentHtml":30,"cover":31,"author":32,"views":19,"readingTime":33,"status":34,"publishedAt":35,"seo":36,"tags":41,"qaPairs":42,"meta":47,"updatedAt":48,"createdAt":49,"_status":50},184,"Penetration Techniques - Obtaining PowerShell Command History","penetration-techniques-obtaining-powershell-command-history","Learn how to exploit PowerShell command history for sensitive data in penetration testing, including export methods and defense strategies to protect credentials.",{"root":16},{"type":17,"format":18,"indent":19,"version":20,"children":21,"direction":29},"root","",0,1,[22],{"type":23,"format":18,"indent":19,"version":20,"children":24,"direction":29},"paragraph",[25],{"mode":26,"text":27,"type":28,"style":18,"detail":19,"format":19,"version":20},"normal","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>During my recent studies, I discovered that PowerShell command history sometimes contains sensitive system information, such as connection credentials for remote servers. Therefore, I conducted further research on PowerShell's history functionality, summarized common methods for exporting history in penetration testing, combined with exploitation ideas, and provided defense recommendations.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following topics:\u003C\u002Fp>\u003Cul>\u003Cli>Two types of PowerShell command history\u003C\u002Fli>\u003Cli>Methods for exporting PowerShell command history\u003C\u002Fli>\u003Cli>Defense recommendations\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Two Types of PowerShell Command History\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>There are two ways to record PowerShell command history, which can be read using Get-History and Get-PSReadlineOption respectively.\u003C\u002Fp>\u003Ch3>1. Get-History\u003C\u002Fh3>\u003Cp>Reference documentation:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fpowershell\u002Fmodule\u002FMicrosoft.PowerShell.Core\u002FGet-History?view=powershell-3.0\u003C\u002Fp>\u003Cp>Default support for PowerShell v2 and above\u003C\u002Fp>\u003Cp>Records commands entered in the current session, not shared between multiple PowerShell processes, all records are automatically cleared after the PowerShell process exits\u003C\u002Fp>\u003Ch4>1. Common Commands\u003C\u002Fh4>\u003Cp>Get complete information of history records:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Get-History | Format-List -Property *\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Includes:\u003C\u002Fp>\u003Cul>\u003Cli>Id\u003C\u002Fli>\u003Cli>CommandLine\u003C\u002Fli>\u003Cli>ExecutionStatus\u003C\u002Fli>\u003Cli>StartExecutionTime\u003C\u002Fli>\u003Cli>EndExecutionTime\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Test as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017234308_0_b906717e6e.jpeg\">\u003C\u002Fp>\u003Cp>Delete all history records:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Clear-History\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Delete command by ID:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Clear-History -Id 3\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch4>2. Exploitation Approach\u003C\u002Fh4>\u003Cp>Gained access to a Windows system, discovered a PowerShell process running in the background, and wanted to read the command history from the PowerShell process\u003C\u002Fp>\u003Cp>(1) PowerShell process cannot receive keyboard input commands\u003C\u002Fp>\u003Cp>For example, PowerShell loaded a script running in the background: PowerShell -ep bypass -f 1.ps1\u003C\u002Fp>\u003Cp>In this case, keyboard messages cannot be sent to the PowerShell process. Useful information can be obtained by reading the command-line arguments of the process. Open-source code:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code implements reading command-line arguments of a specified process, often yielding useful information\u003C\u002Fp>\u003Cp>(2) PowerShell process can receive keyboard input commands\u003C\u002Fp>\u003Cp>Here, keyboard messages can be simulated to export the command history\u003C\u002Fp>\u003Cp>Program implementation approach:\u003C\u002Fp>\u003Cul>\u003Cli>By traversing and enumerating all windows\u003C\u002Fli>\u003Cli>Obtain PID from window (HWND) via GetWindowThreadProcessId\u003C\u002Fli>\u003Cli>Compare PIDs to find the qualifying window\u003C\u002Fli>\u003Cli>Send keyboard messages (PostMessage) to the qualifying window\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Program details:\u003C\u002Fp>\u003Cp>1. Virtual-Key Codes\u003C\u002Fp>\u003Cp>Each keyboard input message corresponds to a Virtual-Key Code\u003C\u002Fp>\u003Cp>Reference:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fwindows\u002Fdesktop\u002Finputdev\u002Fvirtual-key-codes\u003C\u002Fp>\u003Cp>Need to simulate both key press and key release operations, open-source test code:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code implements searching for a process with a specified PID, sending keyboard messages to the process, with the content: whoami\u003C\u002Fp>\u003Cp>2. Export history records\u003C\u002Fp>\u003Cp>Command as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Get-History|export-csv $env:temp\"\\history.csv\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Special characters such as \"|\", \"$\", and \"\"\" need to be considered; the Shift key must be pressed when simulating keyboard input\u003C\u002Fp>\u003Cp>The implementation method here is to first use keybd_event to press the Shift key, then use PostMessage to send the key letters, and finally release both keys\u003C\u002Fp>\u003Cp>Open source test code:\u003C\u002Fp>\u003Cp>An open-source project).cpp\u003C\u002Fp>\u003Cp>The code implements searching for a process with a specified PID and sending keyboard messages to the process, with the content: Get-History|export-csv $env:temp\"\\history.csv\"\u003C\u002Fp>\u003Ch4>3. Additional: View cmd.exe history\u003C\u002Fh4>\u003Cp>Command as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>doskey \u002Fh\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Clear:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>doskey \u002Freinstall\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>It is also possible to export cmd.exe command history by sending keyboard messages\u003C\u002Fp>\u003Ch3>2. Get-PSReadlineOption\u003C\u002Fh3>\u003Cp>Reference documentation:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fpowershell\u002Fmodule\u002Fpsreadline\u002F?view=powershell-5.1\u003C\u002Fp>\u003Cp>Default support for PowerShell v5\u003C\u002Fp>\u003Cp>PowerShell v3 and PowerShell v4 require installation of Get-PSReadlineOption before use\u003C\u002Fp>\u003Cp>After installation, all PowerShell command history is saved in the same location and can be viewed at any time\u003C\u002Fp>\u003Ch4>1. Installation and Usage of PowerShell v3 and PowerShell v4\u003C\u002Fh4>\u003Cp>Taking a 64-bit system as an example, the installation method is as follows:\u003C\u002Fp>\u003Cp>(1) Install PowerShellGet\u003C\u002Fp>\u003Cp>Download:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fwww.microsoft.com\u002Fen-us\u002Fdownload\u002Fdetails.aspx?id=51451\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>The PowerShell process must be closed before installation.\u003C\u002Fp>\u003Cp>Stealth installation can be achieved via command line with the following command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>msiexec \u002Fq \u002Fi PackageManagement_x64.msi\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>After successful installation, it will appear in the installed programs list (Control Panel\\Programs\\Programs and Features) as: Package Management Preview - x64\u003C\u002Fp>\u003Cp>It can be hidden by deleting the corresponding registry entry. For more details, refer to 'Penetration Basics - Obtaining the List of Installed Programs on the Current System'.\u003C\u002Fp>\u003Cp>The registry path for Package Management Preview - x64 is HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{57E5A8BB-41EB-4F09-B332-B535C5954A28}\u003C\u002Fp>\u003Cp>Simply delete this registry key and its subkeys to hide it from the installed programs list.\u003C\u002Fp>\u003Cp>CMD command to delete the registry key:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>reg delete HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{57E5A8BB-41EB-4F09-B332-B535C5954A28} \u002Ff\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>(2) Install PSReadLine\u003C\u002Fp>\u003Cp>Install via Install-Module command\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Install-Module -Name PSReadLine\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Prompt appears:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>NuGet provider is required to continue\u003Cbr>PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact\u003Cbr>with NuGet-based repositories. The NuGet provider must be available in\u003Cbr>'C:\\Program Files\\PackageManagement\\ProviderAssemblies' or\u003Cbr>'C:\\Users\\Administrator\\AppData\\Local\\PackageManagement\\ProviderAssemblies'.\u003Cbr>You can also install the NuGet provider by running 'Install-PackageProvider\u003Cbr>-Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to\u003Cbr>install and import the NuGet provider now?\u003Cbr>[Y] Yes  [N] No  [S] Suspend  [?] Help (default is \"Y\"):\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Need to enter Y again for installation\u003C\u002Fp>\u003Cp>To achieve one-click installation, you can first install NuGet, then install PSReadLine. The complete commands are as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force\u003Cbr>Set-PSRepository -Name PSGallery -InstallationPolicy Trusted\u003Cbr>Install-Module -Name PSReadLine\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>(3) Usage\u003C\u002Fp>\u003Cp>All PowerShell commands will be saved at a fixed location: %appdata%\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt\u003C\u002Fp>\u003Cp>View command history:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Get-Content (Get-PSReadlineOption).HistorySavePath\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Clear command history:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Remove-Item (Get-PSReadlineOption).HistorySavePath\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch4>2. Exploitation Approach\u003C\u002Fh4>\u003Cp>After gaining access to a Windows system, first check the PowerShell version. If it is v5, you can obtain the history by reading the file %appdata%\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt\u003C\u002Fp>\u003Cp>If the system uses PowerShell v3 or v4, you can install PSReadLine via the command line to record all subsequent PowerShell commands on the system\u003C\u002Fp>\u003Ch2>0x03 Defense Recommendations\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>If using a higher version of Windows, such as Win10, where the default PowerShell version is 5.0 and it records PowerShell commands, it is recommended to periodically clear the history. Location: %appdata%\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt\u003C\u002Fp>\u003Cp>Clear command history:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Remove-Item (Get-PSReadlineOption).HistorySavePath\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For older versions of PowerShell, if commands contain sensitive information (such as remote connection passwords), they should be cleared promptly using the command: Clear-History\u003C\u002Fp>\u003Cp>For cmd.exe, if commands contain sensitive information (such as remote connection passwords), they should be cleared promptly using the command: doskey \u002Freinstall\u003C\u002Fp>\u003Ch2>0x04 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article introduces two types of PowerShell command history, summarizes common methods for exporting history records, combines exploitation ideas, and provides defense recommendations.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>","text","ltr","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>During my recent studies, I discovered that PowerShell command history sometimes contains sensitive system information, such as connection credentials for remote servers. Therefore, I conducted further research on PowerShell's history functionality, summarized common methods for exporting history in penetration testing, combined with exploitation ideas, and provided defense recommendations.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following topics:\u003C\u002Fp>\u003Cul>\u003Cli>Two types of PowerShell command history\u003C\u002Fli>\u003Cli>Methods for exporting PowerShell command history\u003C\u002Fli>\u003Cli>Defense recommendations\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Two Types of PowerShell Command History\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>There are two ways to record PowerShell command history, which can be read using Get-History and Get-PSReadlineOption respectively.\u003C\u002Fp>\u003Ch3>1. Get-History\u003C\u002Fh3>\u003Cp>Reference documentation:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fpowershell\u002Fmodule\u002FMicrosoft.PowerShell.Core\u002FGet-History?view=powershell-3.0\u003C\u002Fp>\u003Cp>Default support for PowerShell v2 and above\u003C\u002Fp>\u003Cp>Records commands entered in the current session, not shared between multiple PowerShell processes, all records are automatically cleared after the PowerShell process exits\u003C\u002Fp>\u003Ch4>1. Common Commands\u003C\u002Fh4>\u003Cp>Get complete information of history records:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Get-History | Format-List -Property *\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Includes:\u003C\u002Fp>\u003Cul>\u003Cli>Id\u003C\u002Fli>\u003Cli>CommandLine\u003C\u002Fli>\u003Cli>ExecutionStatus\u003C\u002Fli>\u003Cli>StartExecutionTime\u003C\u002Fli>\u003Cli>EndExecutionTime\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Test as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017234308_0_b906717e6e-1.jpeg\">\u003C\u002Fp>\u003Cp>Delete all history records:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Clear-History\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Delete command by ID:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Clear-History -Id 3\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch4>2. Exploitation Approach\u003C\u002Fh4>\u003Cp>Gained access to a Windows system, discovered a PowerShell process running in the background, and wanted to read the command history from the PowerShell process\u003C\u002Fp>\u003Cp>(1) PowerShell process cannot receive keyboard input commands\u003C\u002Fp>\u003Cp>For example, PowerShell loaded a script running in the background: PowerShell -ep bypass -f 1.ps1\u003C\u002Fp>\u003Cp>In this case, keyboard messages cannot be sent to the PowerShell process. Useful information can be obtained by reading the command-line arguments of the process. Open-source code:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code implements reading command-line arguments of a specified process, often yielding useful information\u003C\u002Fp>\u003Cp>(2) PowerShell process can receive keyboard input commands\u003C\u002Fp>\u003Cp>Here, keyboard messages can be simulated to export the command history\u003C\u002Fp>\u003Cp>Program implementation approach:\u003C\u002Fp>\u003Cul>\u003Cli>By traversing and enumerating all windows\u003C\u002Fli>\u003Cli>Obtain PID from window (HWND) via GetWindowThreadProcessId\u003C\u002Fli>\u003Cli>Compare PIDs to find the qualifying window\u003C\u002Fli>\u003Cli>Send keyboard messages (PostMessage) to the qualifying window\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Program details:\u003C\u002Fp>\u003Cp>1. Virtual-Key Codes\u003C\u002Fp>\u003Cp>Each keyboard input message corresponds to a Virtual-Key Code\u003C\u002Fp>\u003Cp>Reference:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fwindows\u002Fdesktop\u002Finputdev\u002Fvirtual-key-codes\u003C\u002Fp>\u003Cp>Need to simulate both key press and key release operations, open-source test code:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code implements searching for a process with a specified PID, sending keyboard messages to the process, with the content: whoami\u003C\u002Fp>\u003Cp>2. Export history records\u003C\u002Fp>\u003Cp>Command as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Get-History|export-csv $env:temp\"\\history.csv\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Special characters such as \"|\", \"$\", and \"\"\" need to be considered; the Shift key must be pressed when simulating keyboard input\u003C\u002Fp>\u003Cp>The implementation method here is to first use keybd_event to press the Shift key, then use PostMessage to send the key letters, and finally release both keys\u003C\u002Fp>\u003Cp>Open source test code:\u003C\u002Fp>\u003Cp>An open-source project).cpp\u003C\u002Fp>\u003Cp>The code implements searching for a process with a specified PID and sending keyboard messages to the process, with the content: Get-History|export-csv $env:temp\"\\history.csv\"\u003C\u002Fp>\u003Ch4>3. Additional: View cmd.exe history\u003C\u002Fh4>\u003Cp>Command as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>doskey \u002Fh\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Clear:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>doskey \u002Freinstall\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>It is also possible to export cmd.exe command history by sending keyboard messages\u003C\u002Fp>\u003Ch3>2. Get-PSReadlineOption\u003C\u002Fh3>\u003Cp>Reference documentation:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fpowershell\u002Fmodule\u002Fpsreadline\u002F?view=powershell-5.1\u003C\u002Fp>\u003Cp>Default support for PowerShell v5\u003C\u002Fp>\u003Cp>PowerShell v3 and PowerShell v4 require installation of Get-PSReadlineOption before use\u003C\u002Fp>\u003Cp>After installation, all PowerShell command history is saved in the same location and can be viewed at any time\u003C\u002Fp>\u003Ch4>1. Installation and Usage of PowerShell v3 and PowerShell v4\u003C\u002Fh4>\u003Cp>Taking a 64-bit system as an example, the installation method is as follows:\u003C\u002Fp>\u003Cp>(1) Install PowerShellGet\u003C\u002Fp>\u003Cp>Download:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fwww.microsoft.com\u002Fen-us\u002Fdownload\u002Fdetails.aspx?id=51451\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>The PowerShell process must be closed before installation.\u003C\u002Fp>\u003Cp>Stealth installation can be achieved via command line with the following command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>msiexec \u002Fq \u002Fi PackageManagement_x64.msi\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>After successful installation, it will appear in the installed programs list (Control Panel\\Programs\\Programs and Features) as: Package Management Preview - x64\u003C\u002Fp>\u003Cp>It can be hidden by deleting the corresponding registry entry. For more details, refer to 'Penetration Basics - Obtaining the List of Installed Programs on the Current System'.\u003C\u002Fp>\u003Cp>The registry path for Package Management Preview - x64 is HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{57E5A8BB-41EB-4F09-B332-B535C5954A28}\u003C\u002Fp>\u003Cp>Simply delete this registry key and its subkeys to hide it from the installed programs list.\u003C\u002Fp>\u003Cp>CMD command to delete the registry key:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>reg delete HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{57E5A8BB-41EB-4F09-B332-B535C5954A28} \u002Ff\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>(2) Install PSReadLine\u003C\u002Fp>\u003Cp>Install via Install-Module command\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Install-Module -Name PSReadLine\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Prompt appears:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>NuGet provider is required to continue\u003Cbr>PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact\u003Cbr>with NuGet-based repositories. The NuGet provider must be available in\u003Cbr>'C:\\Program Files\\PackageManagement\\ProviderAssemblies' or\u003Cbr>'C:\\Users\\Administrator\\AppData\\Local\\PackageManagement\\ProviderAssemblies'.\u003Cbr>You can also install the NuGet provider by running 'Install-PackageProvider\u003Cbr>-Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to\u003Cbr>install and import the NuGet provider now?\u003Cbr>[Y] Yes  [N] No  [S] Suspend  [?] Help (default is \"Y\"):\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Need to enter Y again for installation\u003C\u002Fp>\u003Cp>To achieve one-click installation, you can first install NuGet, then install PSReadLine. The complete commands are as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force\u003Cbr>Set-PSRepository -Name PSGallery -InstallationPolicy Trusted\u003Cbr>Install-Module -Name PSReadLine\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>(3) Usage\u003C\u002Fp>\u003Cp>All PowerShell commands will be saved at a fixed location: %appdata%\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt\u003C\u002Fp>\u003Cp>View command history:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Get-Content (Get-PSReadlineOption).HistorySavePath\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Clear command history:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Remove-Item (Get-PSReadlineOption).HistorySavePath\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch4>2. Exploitation Approach\u003C\u002Fh4>\u003Cp>After gaining access to a Windows system, first check the PowerShell version. If it is v5, you can obtain the history by reading the file %appdata%\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt\u003C\u002Fp>\u003Cp>If the system uses PowerShell v3 or v4, you can install PSReadLine via the command line to record all subsequent PowerShell commands on the system\u003C\u002Fp>\u003Ch2>0x03 Defense Recommendations\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>If using a higher version of Windows, such as Win10, where the default PowerShell version is 5.0 and it records PowerShell commands, it is recommended to periodically clear the history. Location: %appdata%\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt\u003C\u002Fp>\u003Cp>Clear command history:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Remove-Item (Get-PSReadlineOption).HistorySavePath\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For older versions of PowerShell, if commands contain sensitive information (such as remote connection passwords), they should be cleared promptly using the command: Clear-History\u003C\u002Fp>\u003Cp>For cmd.exe, if commands contain sensitive information (such as remote connection passwords), they should be cleared promptly using the command: doskey \u002Freinstall\u003C\u002Fp>\u003Ch2>0x04 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article introduces two types of PowerShell command history, summarizes common methods for exporting history records, combines exploitation ideas, and provides defense recommendations.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>",765,"Onedaysec",5,"published","2026-02-02T07:38:21.201Z",{"title":37,"description":14,"keywords":38,"ogImage":39,"canonicalUrl":39,"noIndex":40},"PowerShell Command History Penetration Techniques & Defense","PowerShell history, penetration testing, Get-History, Get-PSReadlineOption, command history export, Windows security, defense recommendations",null,false,[],{"docs":43,"hasNextPage":40},[44,45,4,46],749,748,746,{"title":39,"description":39,"image":39},"2026-07-24T15:37:11.631Z","2026-07-23T16:02:02.905Z","draft","2026-07-23T16:14:30.629Z"]