Skip to content

Instantly share code, notes, and snippets.

@alx9r
alx9r / demo.ps1
Created December 20, 2024 18:37
Proof-of-Concept of Cmdlet to protect cleanup from being curtailed by console. (PowerShell/PowerShell#23786)
# add and import the Protect-Cleanup command
Add-Type `
-Path .\protectCleanupCommand.cs `
-PassThru |
% Assembly |
Import-Module
function DivideByZero { [CmdletBinding()]param() 1/0 }
Protect-Cleanup -ErrorStreamProtection ActionPreference {
@alx9r
alx9r / workaround24679.cs
Last active December 19, 2024 00:35
Proof-of-concept of workaround for PowerShell/PowerShell#24679
using System.Management.Automation;
using System.Collections.Generic;
public static class workaround {
public static void Clean (ScriptBlock clean) {
var errorActionPreference = new PSVariable("ErrorActionPreference","SilentlyContinue");
ScriptBlock.Create(@"
param($clean)
try {
. $clean 1
@alx9r
alx9r / testStoppingCleanup.ps1
Last active December 14, 2024 01:00
Test setup for testing PowerShell object lifetime and cleanup when the runspace in which the executing script block is stopped.
# define a type with the following features:
# - can wait for a signal to complete contruction
# - records constructed and disposed flags such that it is beyond object lifetime
Add-Type @'
public class WaitingDisposableMock : System.IDisposable {
// global statics for tracking object lifetime
public static bool Disposed = false;
public static bool Constructed = false;
public WaitingDisposableMock(System.Threading.ManualResetEventSlim waitSignal) {
Disposed = false;
function getSessionState {
param($ScriptBlock)
[scriptblock].
GetProperty('SessionStateInternal',
[System.Reflection.BindingFlags] 'NonPublic, Instance').
GetValue($ScriptBlock)
}
foreach ($method in 'call' ,
'steppable' ) {
@alx9r
alx9r / traceCmdletInternalsCommand.cs
Created December 12, 2024 23:37
Cmdlet for tracing invocations by the PowerShell engine internals
using System;
using System.Management.Automation;
using System.Collections.Concurrent;
[Cmdlet(VerbsDiagnostic.Trace,"CmdletInternals")]
public class TraceCmdletInternalsCommand : Cmdlet, IDisposable {
public static ConcurrentQueue<string> Log { get; set; }
static TraceCmdletInternalsCommand() {
Log = new ConcurrentQueue<string>();
}
@alx9r
alx9r / setCleanupVariableCommand.cs
Last active December 11, 2024 21:23
Proof-of-concept of command combining New-Object and Set-Variable to achieve construction and assignment that can't be interrupted stopping runspace.
using System.Management.Automation;
using System.Management.Automation.Host;
using Automation = System.Management.Automation;
using System.Management.Automation.Runspaces;
using System;
namespace Assuage.PowerShell {
/* This command combines New-Object and Set-Variable to achieve construction and assignment in a manner that cannot be interrupted by the runspace stopping. This is required to ensure reliable cleanup using the assigned-to variable in clean{} because otherwise it is possible for construction, but not, assignment can succeed.
See also:
@alx9r
alx9r / atomicAssignmentSourceMock.cs
Last active December 16, 2024 14:43
Test components and example use for testing PowerShell behavior of assignments, flow control, etc during job stopping
using System;
using System.Management.Automation;
using System.Threading;
// Builder type for the arguments to AtomicAssignmentSourceMock.
// The builder pattern is necessary because the values for Job and PipelineStopping only become available in different threads at different time, and only after a reference to an arguments object is already required.
public class AtomicAssignmentSourceMockArgs {
// flag indicating whether the mock should behave as though this is a dry run
public bool DryRun = false;
@alx9r
alx9r / test.ps1
Last active December 8, 2024 00:19
Test for missed events when subscribed to __InstanceCreationEvent
# https://stackoverflow.com/a/79258729/1404637
param(
[ValidateSet('user','admin')]
$privileges = 'user'
)
function Invoke-Test {
param(
[int]
@alx9r
alx9r / repro.ps1
Last active December 3, 2024 23:21
Repro of lock up raising `CTRL_C_EVENT` from runspace connect via named pipe in `pwsh` job process
# https://stackoverflow.com/a/79248980/1404637
# https://gist.github.com/alx9r/d82232d53356dc5d10eaab1d83458d0e
$before = Get-Process pwsh | % Id
$job = Start-Job {
begin { 'begin' | Set-Content .\log.txt }
end {
Start-Sleep -Seconds 1000
'end' | Add-Content .\log.txt
}
@alx9r
alx9r / test.ps1
Last active May 12, 2020 15:40
Test "no mandatory" parameter binding complex case (PowerShell/PowerShell#11143)
function Where-Object2 {
[CmdletBinding(DefaultParameterSetName='None')]
param(
[Parameter(ValueFromPipeline=$true)]
[psobject]
${InputObject},
[Parameter(ParameterSetName='ScriptBlockSet', Mandatory=$true, Position=0)]
[scriptblock]
${FilterScript},