Allow opt-out of the named-pipe listener using the environment variable POWERSHELL_DIAGNOSTICS_OPTOUT (#26086)

This commit is contained in:
Dongbo Wang
2025-09-30 12:56:54 -07:00
committed by GitHub
parent 716754d220
commit 859431e002
4 changed files with 75 additions and 77 deletions
@@ -24,7 +24,6 @@ using System.Text;
using System.Threading;
using Microsoft.PowerShell.Commands;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using TypeTable = System.Management.Automation.Runspaces.TypeTable;
@@ -1548,6 +1547,72 @@ namespace System.Management.Automation
}
return true;
}
/// <summary>
/// Determine whether the environment variable is set and how.
/// </summary>
/// <param name="name">The name of the environment variable.</param>
/// <param name="defaultValue">If the environment variable is not set, use this as the default value.</param>
/// <returns>A boolean representing the value of the environment variable.</returns>
internal static bool GetEnvironmentVariableAsBool(string name, bool defaultValue)
{
var str = Environment.GetEnvironmentVariable(name);
if (string.IsNullOrEmpty(str))
{
return defaultValue;
}
var boolStr = str.AsSpan();
if (boolStr.Length == 1)
{
if (boolStr[0] == '1')
{
return true;
}
if (boolStr[0] == '0')
{
return false;
}
}
if (boolStr.Length == 3 &&
(boolStr[0] == 'y' || boolStr[0] == 'Y') &&
(boolStr[1] == 'e' || boolStr[1] == 'E') &&
(boolStr[2] == 's' || boolStr[2] == 'S'))
{
return true;
}
if (boolStr.Length == 2 &&
(boolStr[0] == 'n' || boolStr[0] == 'N') &&
(boolStr[1] == 'o' || boolStr[1] == 'O'))
{
return false;
}
if (boolStr.Length == 4 &&
(boolStr[0] == 't' || boolStr[0] == 'T') &&
(boolStr[1] == 'r' || boolStr[1] == 'R') &&
(boolStr[2] == 'u' || boolStr[2] == 'U') &&
(boolStr[3] == 'e' || boolStr[3] == 'E'))
{
return true;
}
if (boolStr.Length == 5 &&
(boolStr[0] == 'f' || boolStr[0] == 'F') &&
(boolStr[1] == 'a' || boolStr[1] == 'A') &&
(boolStr[2] == 'l' || boolStr[2] == 'L') &&
(boolStr[3] == 's' || boolStr[3] == 'S') &&
(boolStr[4] == 'e' || boolStr[4] == 'E'))
{
return false;
}
return defaultValue;
}
}
}
@@ -12,7 +12,6 @@ using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Win32.SafeHandles;
@@ -500,13 +499,14 @@ namespace System.Management.Automation.Remoting
{
s_syncObject = new object();
// All PowerShell instances will start with the named pipe
// and listener created and running.
IPCNamedPipeServerEnabled = true;
// Unless opt-out, all PowerShell instances will start with the named-pipe listener created and running.
IPCNamedPipeServerEnabled = !Utils.GetEnvironmentVariableAsBool(name: "POWERSHELL_DIAGNOSTICS_OPTOUT", defaultValue: false);
CreateIPCNamedPipeServerSingleton();
CreateProcessExitHandler();
if (IPCNamedPipeServerEnabled)
{
CreateIPCNamedPipeServerSingleton();
CreateProcessExitHandler();
}
}
#endregion
@@ -1411,7 +1411,7 @@ All WinRM sessions connected to PowerShell session configurations, such as Micro
<value>Multiple processes were found with this name {0}. Use the process Id to specify a single process to enter.</value>
</data>
<data name="EnterPSHostProcessNoPowerShell" xml:space="preserve">
<value>Cannot enter process with Id '{0}' because it has not loaded the PowerShell engine.</value>
<value>Cannot enter process with Id '{0}' because it has not loaded the PowerShell engine or the named-pipe listener was disabled.</value>
</data>
<data name="EnterPSHostProcessNoProcessFoundWithId" xml:space="preserve">
<value>No process was found with Id: {0}.</value>
@@ -8,7 +8,6 @@ using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Threading;
using Microsoft.ApplicationInsights;
@@ -177,7 +176,7 @@ namespace Microsoft.PowerShell.Telemetry
static ApplicationInsightsTelemetry()
{
// If we can't send telemetry, there's no reason to do any of this
CanSendTelemetry = !GetEnvironmentVariableAsBool(name: _telemetryOptoutEnvVar, defaultValue: false);
CanSendTelemetry = !Utils.GetEnvironmentVariableAsBool(name: _telemetryOptoutEnvVar, defaultValue: false);
if (CanSendTelemetry)
{
s_sessionId = Guid.NewGuid().ToString();
@@ -643,72 +642,6 @@ namespace Microsoft.PowerShell.Telemetry
}
}
/// <summary>
/// Determine whether the environment variable is set and how.
/// </summary>
/// <param name="name">The name of the environment variable.</param>
/// <param name="defaultValue">If the environment variable is not set, use this as the default value.</param>
/// <returns>A boolean representing the value of the environment variable.</returns>
private static bool GetEnvironmentVariableAsBool(string name, bool defaultValue)
{
var str = Environment.GetEnvironmentVariable(name);
if (string.IsNullOrEmpty(str))
{
return defaultValue;
}
var boolStr = str.AsSpan();
if (boolStr.Length == 1)
{
if (boolStr[0] == '1')
{
return true;
}
if (boolStr[0] == '0')
{
return false;
}
}
if (boolStr.Length == 3 &&
(boolStr[0] == 'y' || boolStr[0] == 'Y') &&
(boolStr[1] == 'e' || boolStr[1] == 'E') &&
(boolStr[2] == 's' || boolStr[2] == 'S'))
{
return true;
}
if (boolStr.Length == 2 &&
(boolStr[0] == 'n' || boolStr[0] == 'N') &&
(boolStr[1] == 'o' || boolStr[1] == 'O'))
{
return false;
}
if (boolStr.Length == 4 &&
(boolStr[0] == 't' || boolStr[0] == 'T') &&
(boolStr[1] == 'r' || boolStr[1] == 'R') &&
(boolStr[2] == 'u' || boolStr[2] == 'U') &&
(boolStr[3] == 'e' || boolStr[3] == 'E'))
{
return true;
}
if (boolStr.Length == 5 &&
(boolStr[0] == 'f' || boolStr[0] == 'F') &&
(boolStr[1] == 'a' || boolStr[1] == 'A') &&
(boolStr[2] == 'l' || boolStr[2] == 'L') &&
(boolStr[3] == 's' || boolStr[3] == 'S') &&
(boolStr[4] == 'e' || boolStr[4] == 'E'))
{
return false;
}
return defaultValue;
}
/// <summary>
/// Send module load telemetry as a metric.
/// For modules we send the module name (if allowed), and the version.