|
| 1 | +--- |
| 2 | +description: PowerShell logs internal operations from the engine, providers, and cmdlets to the Windows event log. |
| 3 | +Locale: en-US |
| 4 | +ms.date: 01/03/2024 |
| 5 | +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_logging_windows?view=powershell-7.4&WT.mc_id=ps-gethelp |
| 6 | +schema: 2.0.0 |
| 7 | +title: about_Logging_Windows |
| 8 | +--- |
1 | 9 |
|
| 10 | +# about_Logging_Windows |
2 | 11 |
|
| 12 | +## Short description |
3 | 13 |
|
| 14 | +PowerShell logs internal operations from the engine, providers, and cmdlets to |
| 15 | +the Windows event log. |
4 | 16 |
|
| 17 | +## Long description |
5 | 18 |
|
| 19 | +PowerShell logs details about PowerShell operations, such as starting and |
| 20 | +stopping the engine and providers, and executing PowerShell commands. |
6 | 21 |
|
| 22 | +For information about logging in Windows PowerShell 5.1, see |
| 23 | +[about_Logging][02]. |
7 | 24 |
|
| 25 | +PowerShell supports configuring two categories of logging: |
8 | 26 |
|
| 27 | +- Module logging - Record the pipeline execution events for members of |
| 28 | + specified modules. Module logging must be enabled for both the session and |
| 29 | + specific modules. For more information about configuring this logging, see |
| 30 | + [about_PowerShell_Config][05]. |
9 | 31 |
|
| 32 | + If module logging is enabled through configuration, you can enable and |
| 33 | + disable logging for specific modules in a session by setting the value of the |
| 34 | + **LogPipelineExecutionDetails** property of the module. |
10 | 35 |
|
| 36 | + For example, to enable module logging for the **PSReadLine** module: |
11 | 37 |
|
| 38 | + ```powershell |
| 39 | + $psrl = Get-Module PSReadLine |
| 40 | + $psrl.LogPipelineExecutionDetails = $true |
| 41 | + Get-Module PSReadLine | Select-Object Name, LogPipelineExecutionDetails |
| 42 | + ``` |
12 | 43 |
|
| 44 | + ```Output |
| 45 | + Name LogPipelineExecutionDetails |
| 46 | + ---- --------------------------- |
| 47 | + PSReadLine True |
| 48 | + ``` |
13 | 49 |
|
| 50 | +- Script block logging - Record the processing of commands, script blocks, |
| 51 | + functions, and scripts whether invoked interactively, or through automation. |
14 | 52 |
|
| 53 | + When you enable Script Block Logging, PowerShell records the content of all |
| 54 | + script blocks that it processes. Once enabled, any new PowerShell session |
| 55 | + logs this information. For more information, see |
| 56 | + [Enabling Script Block Logging][03]. |
15 | 57 |
|
| 58 | +## Registering the PowerShell event provider on Windows |
16 | 59 |
|
| 60 | +Unlike Linux or macOS, Windows requires the event provider to be registered |
| 61 | +before events can be written to the event log. To enable the PowerShell event |
| 62 | +provider, run the following command from an elevated PowerShell prompt. |
17 | 63 |
|
| 64 | +```powershell |
| 65 | +$PSHOME\RegisterManifest.ps1 |
| 66 | +``` |
18 | 67 |
|
| 68 | +## Viewing the PowerShell event log entries on Windows |
19 | 69 |
|
| 70 | +PowerShell logs can be viewed using the Windows Event Viewer. The event log is |
| 71 | +located in the **Application and Services Logs** group and is named |
| 72 | +**PowerShellCore**. The associated ETW provider GUID is |
| 73 | +`{f90714a8-5509-434a-bf6d-b1624c8a19a2}`. |
20 | 74 |
|
| 75 | +When Script Block Logging is enabled, PowerShell logs the following events to |
| 76 | +the **PowerShellCore/Operational** log: |
21 | 77 |
|
| 78 | +| Field | Value | |
| 79 | +| ------- | ----------------- | |
| 80 | +| EventId | `4104` / `0x1008` | |
| 81 | +| Channel | `Operational` | |
| 82 | +| Level | `Verbose` | |
| 83 | +| Opcode | `Create` | |
| 84 | +| Task | `CommandStart` | |
| 85 | +| Keyword | `Runspace` | |
22 | 86 |
|
| 87 | +### Unregistering the PowerShell event provider on Windows |
23 | 88 |
|
| 89 | +Registering the event provider places a lock in the binary library used to |
| 90 | +decode events. To update this library, the provider must be unregistered to |
| 91 | +release this lock. |
24 | 92 |
|
| 93 | +To unregister the PowerShell provider, run the following command from an |
| 94 | +elevated PowerShell prompt. |
25 | 95 |
|
| 96 | +```powershell |
| 97 | +$PSHOME\RegisterManifest.ps1 -Unregister |
| 98 | +``` |
26 | 99 |
|
| 100 | +After updating PowerShell, run `$PSHOME\RegisterManifest.ps1` to register the |
| 101 | +updated event provider. |
27 | 102 |
|
| 103 | +## Enabling Script Block Logging |
28 | 104 |
|
| 105 | +When you enable Script Block Logging, PowerShell records the content of all |
| 106 | +script blocks that it processes. Once enabled, any new PowerShell session logs |
| 107 | +this information. |
29 | 108 |
|
| 109 | +> [!NOTE] |
| 110 | +> It's recommended to enable Protected Event Logging, as described below, when |
| 111 | +> using Script Block Logging for anything other than diagnostics purposes. |
30 | 112 |
|
| 113 | +Script Block Logging can be enabled via Group Policy or a registry setting. |
31 | 114 |
|
| 115 | +### Using Group Policy |
32 | 116 |
|
| 117 | +To enable automatic transcription, enable the **Turn on PowerShell Script Block |
| 118 | +Logging** feature in Group Policy through **Administrative Templates** -> |
| 119 | +**PowerShell Core**. |
33 | 120 |
|
| 121 | +### Using the Registry |
34 | 122 |
|
| 123 | +Run the following function: |
35 | 124 |
|
| 125 | +```powershell |
| 126 | +function Enable-PSScriptBlockLogging { |
| 127 | + $basePath = @( |
| 128 | + 'HKLM:\Software\Policies\Microsoft' |
| 129 | + 'PowerShellCore\ScriptBlockLogging' |
| 130 | + ) -join '\' |
36 | 131 |
|
| 132 | + if (-not (Test-Path $basePath)) { |
| 133 | + $null = New-Item $basePath -Force |
| 134 | + } |
37 | 135 |
|
| 136 | + Set-ItemProperty $basePath -Name EnableScriptBlockLogging -Value "1" |
| 137 | +} |
| 138 | +``` |
| 139 | + |
| 140 | +### Using the PowerShell configuration file |
| 141 | + |
| 142 | +You can set the `ScriptBlockLogging` option in the `powershell.config.json` |
| 143 | +file that controls how PowerShell behaves. For more information, see |
| 144 | +[about_PowerShell_Config][06]. |
| 145 | + |
| 146 | +## Protected Event Logging |
38 | 147 |
|
| 148 | +Increasing the level of logging on a system increases the possibility that |
| 149 | +logged content may contain sensitive data. For example, with script logging |
| 150 | +enabled, credentials or other sensitive data used by a script can be written to |
| 151 | +the event log. When a machine that has logged sensitive data is compromised, |
| 152 | +the logs can provide an attacker with information needed to extend their reach. |
| 153 | + |
| 154 | +To protect this information, Windows 10 introduces Protected Event Logging. |
| 155 | +Protected Event Logging lets participating applications encrypt sensitive data |
| 156 | +written to the event log. Later, you can decrypt and process these logs on a |
| 157 | +more secure and centralized log collector. |
39 | 158 |
|
| 159 | +Event log content is protected using the IETF Cryptographic Message Syntax |
| 160 | +(CMS) standard. CMS uses public key cryptography. The keys used to encrypt |
| 161 | +content and decrypt content are kept separate. |
40 | 162 |
|
| 163 | +The public key can be shared widely and isn't sensitive data. Any content |
| 164 | +encrypted with this public key can only be decrypted by the private key. For |
| 165 | +more information about Public Key Cryptography, see |
| 166 | +[Wikipedia - Public Key Cryptography][08]. |
41 | 167 |
|
| 168 | +To enable a Protected Event Logging policy, deploy a public key to all machines |
| 169 | +that have event log data to protect. The corresponding private key is used to |
| 170 | +post-process the event logs at a more secure location such as a central event |
| 171 | +log collector, or [SIEM][09] aggregator. You can set up SIEM in Azure. For more |
| 172 | +information, see [Generic SIEM integration][01]. |
| 173 | + |
| 174 | +### Enabling Protected Event Logging via Group Policy |
| 175 | + |
| 176 | +To enable Protected Event Logging, enable the `Enable Protected Event Logging` |
| 177 | +feature in Group Policy through `Administrative Templates -> Windows Components |
| 178 | +-> Event Logging`. This setting requires an encryption certificate, which you |
| 179 | +can provide in one of several forms: |
| 180 | + |
| 181 | +- The content of a base-64 encoded X.509 certificate (for example, as offered |
| 182 | + by the `Export` option in Certificate Manager). |
| 183 | +- The thumbprint of a certificate that can be found in the Local Machine |
| 184 | + certificate store (can be deployed by PKI infrastructure). |
| 185 | +- The full path to a certificate (can be local, or a remote share). |
| 186 | +- The path to a directory containing a certificate or certificates (can be |
| 187 | + local, or a remote share). |
| 188 | +- The subject name of a certificate that can be found in the Local Machine |
| 189 | + certificate store (can be deployed by PKI infrastructure). |
42 | 190 |
|
| 191 | +The resulting certificate must have `Document Encryption` as an enhanced key |
| 192 | +usage (`1.3.6.1.4.1.311.80.1`), and either `Data Encipherment` or |
| 193 | +`Key Encipherment` key usages enabled. |
43 | 194 |
|
| 195 | +> [!WARNING] |
| 196 | +> The private key shouldn't be deployed to the machines logging events. It |
| 197 | +> should be kept in a secure location where you decrypt the messages. |
44 | 198 |
|
45 | | - |
46 | | - |
47 | | - |
48 | | - |
49 | | - |
50 | | - |
51 | | - |
52 | | - |
53 | | - |
54 | | - |
55 | | - |
56 | | - |
57 | | - |
58 | | - |
59 | | - |
60 | | - |
61 | | - |
62 | | - |
63 | | - |
64 | | - |
65 | | - |
66 | | - |
67 | | - |
68 | | - |
69 | | - |
70 | | - |
71 | | - |
72 | | - |
73 | | - |
74 | | - |
75 | | - |
76 | | - |
77 | | - |
78 | | - |
79 | | - |
80 | | - |
81 | | - |
82 | | - |
83 | | - |
84 | | - |
85 | | - |
86 | | - |
87 | | - |
88 | | - |
89 | | - |
90 | | - |
91 | | - |
92 | | - |
93 | | - |
94 | | - |
95 | | - |
96 | | - |
97 | | - |
98 | | - |
99 | | - |
100 | | - |
101 | | - |
102 | | - |
103 | | - |
104 | | - |
105 | | - |
106 | | - |
107 | | - |
108 | | - |
109 | | - |
110 | | - |
111 | | - |
112 | | - |
113 | | - |
114 | | - |
115 | | - |
116 | | - |
117 | | - |
118 | | - |
119 | | - |
120 | | - |
121 | | - |
122 | | - |
123 | | - |
124 | | - |
125 | | - |
126 | | - |
127 | | - |
128 | | - |
129 | | - |
130 | | - |
131 | | - |
132 | | - |
133 | | - |
134 | | - |
135 | | - |
136 | | - |
137 | | - |
138 | | - |
139 | | - |
140 | | - |
141 | | - |
142 | | - |
143 | | - |
144 | | -[about_PowerSh`ell_Config][06]. |
| 199 | +### Decrypting Protected Event Logging messages |
| 200 | + |
| 201 | +The following script retrieves and decrypts events, assuming that you have the |
| 202 | +private key: |
| 203 | + |
| 204 | +```powershell |
| 205 | +Get-WinEvent Microsoft-Windows-PowerShell/Operational | |
| 206 | + Where-Object Id -EQ 4104 | Unprotect-CmsMessage |
| 207 | +``` |
| 208 | + |
| 209 | +## See also |
| 210 | + |
| 211 | +- [about_Logging_Non-Windows][04] |
| 212 | +- [PowerShell the Blue Team][07] |
| 213 | +- [Generic SIEM integration][01] |
| 214 | + |
| 215 | +<!-- link references --> |
| 216 | +[01]: /cloud-app-security/siem |
| 217 | +[02]: /powershell/module/microsoft.powershell.core/about/about_logging?view=powershell-5.1&preserve-view=true |
| 218 | +[03]: #enabling-script-block-logging |
| 219 | +[04]: about_Logging_Non-Windows.md |
| 220 | +[05]: about_PowerShell_Config.md#modulelogging |
| 221 | +[06]: about_PowerShell_Config.md#scriptblocklogging |
| 222 | +[07]: https://devblogs.microsoft.com/powershell/powershell-the-blue-team/ |
| 223 | +[08]: https://en.wikipedia.org/wiki/Public-key_cryptography |
| 224 | +[09]: https://wikipedia.org/wiki/Security_information_and_event_management |
0 commit comments