Hi all, I want to share a simple script that can run a Powershell script & dump all of its variables to output.txt
This is useful because our script does NOT modify the original PS script, so it works with any. It also catches program crashes so you can get variables no matter when/where it exits!
Here is our wrapper.ps1 file that calls original.ps1 and catches all variables in runtime:
For testing, here is original.ps1 which I used:
To bring it all together, you could put the original.ps1 code into wrapper.ps1, and you could then package wrapper.ps1 into a C++ program or similar. It's up to you! I was helping out another user and they are going to modify this code for another use case & said I could share this. I hope this helps some others here too, but remember this is just a POC on variable dumping and is not a "final program" for anything specific. Use at your own risk, for educational & personal & legal uses only.
Here is an example log from command prompt / cmd.exe :
Here is the associated output.txt from the runtime dump:
This is useful because our script does NOT modify the original PS script, so it works with any. It also catches program crashes so you can get variables no matter when/where it exits!
Here is our wrapper.ps1 file that calls original.ps1 and catches all variables in runtime:
Code
# Get the directory where this script is located
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
# Define the path to the original script
$scriptPath = Join-Path -Path $scriptDir -ChildPath "original.ps1"
try {
# Attempt to execute the original script
. $scriptPath
} catch {
# Handle errors from the original script (if it fails, crashes, or throws any error)
Write-Host "An error occurred: $_"
} finally {
# Capture all variables before the script exits, regardless of the outcome
Get-Variable | Where-Object {
$_.Name -notin @('scriptDir', 'scriptPath', 'HOME', 'PWD', 'PSVersionTable', 'Host', 'true', 'false', 'null', 'Error', 'LASTEXITCODE')
} | ForEach-Object {
"$($_.Name) = $($_.Value)" | Out-File "output.txt" -Append
}
# Optionally, log the completion of variable capture
Write-Host "Variable capture complete."
}
# Check if the last exit code signals an error (from external programs or the script itself if it sets $LASTEXITCODE)
if ($LASTEXITCODE -ne 0) {
Write-Host "The script exited with an error code: $LASTEXITCODE"
}For testing, here is original.ps1 which I used:
Code
# original.ps1 - Example PowerShell script with various operations and intentional error
# Define some variables
$var1 = "Hello World"
$var2 = 25
$var3 = @{ Name = "Sample"; Value = 42 }
# Print variable values
Write-Host "var1: $var1"
Write-Host "var2: $var2"
Write-Host "var3: $($var3.Name), $($var3.Value)"
# Perform a calculation
$result = $var2 * 3
Write-Host "Result of calculation: $result"
# Introduce an error
Write-Host "Attempting an operation that will fail..."
$failedOperation = 1 / 0 # This division by zero will trigger an exception
# If the script reaches here, it means the error was not fatal
Write-Host "This line will not be executed because of the preceding error."To bring it all together, you could put the original.ps1 code into wrapper.ps1, and you could then package wrapper.ps1 into a C++ program or similar. It's up to you! I was helping out another user and they are going to modify this code for another use case & said I could share this. I hope this helps some others here too, but remember this is just a POC on variable dumping and is not a "final program" for anything specific. Use at your own risk, for educational & personal & legal uses only.
Here is an example log from command prompt / cmd.exe :
Quote:var1: Hello World
var2: 25
var3: Sample, 42
Result of calculation: 75
Attempting an operation that will fail...
An error occurred: Attempted to divide by zero.
Variable capture complete.
The script exited with an error code:
PowerShell script executed and variables captured.
Here is the associated output.txt from the runtime dump:
Quote:$ =
? = True
^ =
_ =
args =
ConfirmPreference = High
ConsoleFileName =
DebugPreference = SilentlyContinue
ErrorActionPreference = Continue
ErrorView = NormalView
ExecutionContext = System.Management.Automation.EngineIntrinsics
FormatEnumerationLimit = 4
InformationPreference = SilentlyContinue
input =
MaximumAliasCount = 4096
MaximumDriveCount = 4096
MaximumErrorCount = 256
MaximumFunctionCount = 4096
MaximumHistoryCount = 4096
MaximumVariableCount = 4096
MyInvocation = System.Management.Automation.InvocationInfo
NestedPromptLevel = 0
OutputEncoding = System.Text.ASCIIEncoding
PID = 49196
PROFILE = C:\Users\nodes\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
ProgressPreference = Continue
PSBoundParameters = System.Management.Automation.PSBoundParametersDictionary
PSCommandPath = C:\Users\nodes\Desktop\Personal\C++\DumpPS\x64\Debug\original.ps1
PSCulture = en-US
PSDefaultParameterValues = System.Management.Automation.DefaultParameterDictionary
PSEdition = Desktop
PSEmailServer =
PSHOME = C:\Windows\System32\WindowsPowerShell\v1.0
PSItem =
PSScriptRoot = C:\Users\nodes\Desktop\Personal\C++\DumpPS\x64\Debug
PSSessionApplicationName = wsman
PSSessionConfigurationName = http://schemas.microsoft.com/powershell/...PowerShell
PSSessionOption = System.Management.Automation.Remoting.PSSessionOption
PSUICulture = en-US
result = 75
ShellId = Microsoft.PowerShell
StackTrace = at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
var1 = Hello World
var2 = 25
var3 = System.Collections.Hashtable
VerbosePreference = SilentlyContinue
WarningPreference = Continue
WhatIfPreference = False



![[Image: nodeslovesrussia.png]](https://i.ibb.co/Nskr6x9/nodeslovesrussia.png)

![[Image: main.gif]](https://i.ibb.co/W2WKpzj/main.gif)
![[Image: main.gif]](https://i.ibb.co/MZkhhV6/main.gif)