From 21639d184e81854caa846118673b04deb118c523 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sat, 5 Sep 2026 10:25:41 +0200 Subject: [PATCH 1/5] Removed App Insights. Cmdlets are kept present, functionally don't do anything anymore and have been marked obsolete. --- CHANGELOG.md | 1 + build/Build-Debug.ps1 | 1 - build/Build-Nightly.ps1 | 4 +- build/Build-Release.ps1 | 2 - .../Disable-PnPPowerShellTelemetry.md | 3 + .../Enable-PnPPowerShellTelemetry.md | 3 + .../Get-PnPPowerShellTelemetryEnabled.md | 3 + pages/articles/telemetry.md | 18 +---- src/ALC/ApplicationInsights.cs | 73 ------------------- src/ALC/PnP.PowerShell.ALC.csproj | 13 ---- src/ALC/TelemetryClient.cs | 37 ---------- .../Base/DisablePowerShellTelemetry.cs | 25 +------ .../Base/EnablePowerShellTelemetry.cs | 22 +----- .../Base/GetPowerShellTelemetryEnabled.cs | 8 +- src/Commands/Base/PnPAssemblyLoadContext.cs | 4 +- src/Commands/Base/PnPConnectedCmdlet.cs | 6 -- src/Commands/Base/PnPConnection.cs | 60 +-------------- .../Base/PnPPowerShellModuleInitializer.cs | 2 + src/Commands/PnP.PowerShell.Release.csproj | 8 +- src/Commands/PnP.PowerShell.csproj | 9 ++- src/Commands/_debug/debug.ps1 | 2 +- src/PnP.PowerShell.sln | 8 -- src/Tests/PnP.PowerShell.Tests.csproj | 1 - 23 files changed, 45 insertions(+), 268 deletions(-) delete mode 100644 src/ALC/ApplicationInsights.cs delete mode 100644 src/ALC/PnP.PowerShell.ALC.csproj delete mode 100644 src/ALC/TelemetryClient.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index d594a5956c..c8d691c065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added ### Changed +- Marked `Get-PnPPowerShellTelemetryEnabled`, `Enable-PnPPowerShellTelemetry` and `Disable-PnPPowerShellTelemetry` as deprecated. These cmdlets will be removed in the next release. ### Fixed - Using UPNs with an apostrophe in it not working with `Remove-PnPUserProfile`, `Export-PnPUserProfile`, `Export-PnPUserInfo`, and `Remove-PnPUserInfo`. The apostrophe is now escaped in the API request. [#5459](https://github.com/pnp/powershell/pull/5459) diff --git a/build/Build-Debug.ps1 b/build/Build-Debug.ps1 index dd43d78ea9..4e0709996c 100644 --- a/build/Build-Debug.ps1 +++ b/build/Build-Debug.ps1 @@ -136,7 +136,6 @@ if ($LASTEXITCODE -eq 0) { Copy-Item -Path "$PSScriptRoot/../resources/*.ps1xml" -Destination "$destinationFolder" # ScriptsToProcess bootstrap that registers the isolated-dependency resolver before the binary module loads. Copy-Item -Path "$PSScriptRoot/../resources/RegisterPnPAssemblyResolver.ps1" -Destination "$destinationFolder" - Get-ChildItem -Path "$PSScriptRoot/../src/ALC/bin/Debug/net8.0" | Where-Object { $_.Extension -in '.dll', '.pdb' } | Foreach-Object { [void]$commonFiles.Add($_.Name); Copy-Item -LiteralPath $_.FullName -Destination $commonPath } Get-ChildItem -Path "$PSScriptRoot/../src/Commands/bin/Debug/$configuration" | Where-Object { $_.Extension -in '.dll', '.pdb' } | Foreach-Object { if ($moduleAssemblies -contains $_.Name -or $_.Name -like 'Microsoft.SharePoint.Client*' -or $_.Name -like 'Microsoft.Online.SharePoint.Client*') { Copy-Item -LiteralPath $_.FullName -Destination $corePath diff --git a/build/Build-Nightly.ps1 b/build/Build-Nightly.ps1 index e5a1f493fc..22910e3eaf 100644 --- a/build/Build-Nightly.ps1 +++ b/build/Build-Nightly.ps1 @@ -117,7 +117,6 @@ if ($runPublish -eq $true) { Copy-Item -Path "$PSscriptRoot/../resources/*.ps1xml" -Destination "$destinationFolder" # ScriptsToProcess bootstrap that registers the isolated-dependency resolver before the binary module loads. Copy-Item -Path "$PSscriptRoot/../resources/RegisterPnPAssemblyResolver.ps1" -Destination "$destinationFolder" - Get-ChildItem -Path "$PSScriptRoot/../src/ALC/bin/Release/net8.0" | Where-Object { $_.Extension -in '.dll', '.pdb' } | Foreach-Object { [void]$commonFiles.Add($_.Name); Copy-Item -LiteralPath $_.FullName -Destination $commonPath } Get-ChildItem -Path "$PSScriptRoot/../src/Commands/bin/Release/net8.0" | Where-Object { $_.Extension -in '.dll', '.pdb' } | Foreach-Object { if ($moduleAssemblies -contains $_.Name -or $_.Name -like 'Microsoft.SharePoint.Client*' -or $_.Name -like 'Microsoft.Online.SharePoint.Client*') { Copy-Item -LiteralPath $_.FullName -Destination $corePath @@ -294,8 +293,7 @@ if ($runPublish -eq $true) { Get-Item -LiteralPath "$commonPath/PnP.Core.Admin.dll" Get-Item -LiteralPath "$commonPath/PnP.Core.Auth.dll" Get-Item -LiteralPath "$commonPath/PnP.Framework.dll" - Get-Item -LiteralPath "$commonPath/PnP.PowerShell.ALC.dll" - ) + ) foreach ($assemblyToBeSigned in $assembliesToBeSigned) { Invoke-ModuleFileSigning -File $assemblyToBeSigned diff --git a/build/Build-Release.ps1 b/build/Build-Release.ps1 index b2174a3845..31e0c8528a 100644 --- a/build/Build-Release.ps1 +++ b/build/Build-Release.ps1 @@ -58,7 +58,6 @@ Try { Copy-Item -Path "$PSscriptRoot/../resources/*.ps1xml" -Destination "$destinationFolder" # ScriptsToProcess bootstrap that registers the isolated-dependency resolver before the binary module loads. Copy-Item -Path "$PSscriptRoot/../resources/RegisterPnPAssemblyResolver.ps1" -Destination "$destinationFolder" - Get-ChildItem -Path "$PSScriptRoot/../src/ALC/bin/Release/net8.0" | Where-Object { $_.Extension -in '.dll', '.pdb' } | Foreach-Object { [void]$commonFiles.Add($_.Name); Copy-Item -LiteralPath $_.FullName -Destination $commonPath } Get-ChildItem -Path "$PSScriptRoot/../src/Commands/bin/Release/net8.0" | Where-Object { $_.Extension -in '.dll', '.pdb' } | Foreach-Object { if ($moduleAssemblies -contains $_.Name -or $_.Name -like 'Microsoft.SharePoint.Client*' -or $_.Name -like 'Microsoft.Online.SharePoint.Client*') { Copy-Item -LiteralPath $_.FullName -Destination $corePath @@ -234,7 +233,6 @@ $assembliesToBeSigned = @( Get-Item -LiteralPath "$commonPath/PnP.Core.Admin.dll" Get-Item -LiteralPath "$commonPath/PnP.Core.Auth.dll" Get-Item -LiteralPath "$commonPath/PnP.Framework.dll" - Get-Item -LiteralPath "$commonPath/PnP.PowerShell.ALC.dll" ) foreach ($assemblyToBeSigned in $assembliesToBeSigned) { diff --git a/documentation/Disable-PnPPowerShellTelemetry.md b/documentation/Disable-PnPPowerShellTelemetry.md index 1d1a7ecd4a..6643e5a8a3 100644 --- a/documentation/Disable-PnPPowerShellTelemetry.md +++ b/documentation/Disable-PnPPowerShellTelemetry.md @@ -9,6 +9,9 @@ online version: https://pnp.github.io/powershell/cmdlets/Disable-PnPPowerShellTe # Disable-PnPPowerShellTelemetry +> [!WARNING] +> This cmdlet is deprecated and will be removed in the next release. + ## SYNOPSIS Disables sending of telemetry data. diff --git a/documentation/Enable-PnPPowerShellTelemetry.md b/documentation/Enable-PnPPowerShellTelemetry.md index c1c027b123..fee91aa5e3 100644 --- a/documentation/Enable-PnPPowerShellTelemetry.md +++ b/documentation/Enable-PnPPowerShellTelemetry.md @@ -9,6 +9,9 @@ online version: https://pnp.github.io/powershell/cmdlets/Enable-PnPPowerShellTel # Enable-PnPPowerShellTelemetry +> [!WARNING] +> This cmdlet is deprecated and will be removed in the next release. + ## SYNOPSIS Enables sending of telemetry data. diff --git a/documentation/Get-PnPPowerShellTelemetryEnabled.md b/documentation/Get-PnPPowerShellTelemetryEnabled.md index ca2ef640d8..83e6617a54 100644 --- a/documentation/Get-PnPPowerShellTelemetryEnabled.md +++ b/documentation/Get-PnPPowerShellTelemetryEnabled.md @@ -9,6 +9,9 @@ online version: https://pnp.github.io/powershell/cmdlets/Get-PnPPowerShellTeleme # Get-PnPPowerShellTelemetryEnabled +> [!WARNING] +> This cmdlet is deprecated and will be removed in the next release. + ## SYNOPSIS Returns true if the PnP PowerShell Telemetry has been enabled. diff --git a/pages/articles/telemetry.md b/pages/articles/telemetry.md index 67a5850c00..c3b76e8856 100644 --- a/pages/articles/telemetry.md +++ b/pages/articles/telemetry.md @@ -1,17 +1,5 @@ -# Disable or Enable telemetry +# Telemetry in PnP PowerShell -By default PnP PowerShell will report its usage anonymously to the PnP team. We collection information about the **version of PnP PowerShell**, the **operation system version** and the **cmdlet** executed. Notice that we will *not* include parameters used and we will *not* include any values of parameters. We will also *not* be able to trace the execution back to the specific tenant it ran on, the organization it was used for or the person it was run by. Having telemtry in place allows us to get insight in the usage of cmdlets and thereby prioritize work towards the most popular cmdlets. +Up to September 4th, 2026, PnP PowerShell reported its usage anonymously to the PnP team. We collected information about the **version of PnP PowerShell**, the **operation system version** and the **cmdlet** executed. Notice that we did *not* include parameters used and we did *not* include any values of parameters. We were also *not* be able to trace the execution back to the specific tenant it ran on, the organization it was used for or the person it was run by. Having had telemetry in place allowed us to get insight in the usage of cmdlets and thereby prioritize work towards the most popular cmdlets. Over the years the popularity of PnP PowerShell has grown to a level where the costs of collecting and storing all this data became a substantial amount. We have therefore decided to stop collecting this data as the costs no longer outweighed the advantages of us having insights into the usage. The endpoint for the telemetry collection has been removed. Starting with version 3.4.2 the sending of telemetry has been removed from the PowerShell module. Any prior versions will still try to submit telemetry, but submitting the telemetry will no longer succeed. It will not interfere with the normal execution of your PowerShell scripts. -To query if in a connected PnP PowerShell session the telemetry is enabled, use [Get-PnPPowerShellTelemetryEnabled](../cmdlets/Get-PnPPowerShellTelemetryEnabled.md). - -If you wish to control telemetry to be sent, you can use one of the below options. - -## By using PnP PowerShell -You can disable telemetry to be sent by using [Disable-PnPPowerShellTelemetry](../cmdlets/Disable-PnPPowerShellTelemetry.md). -You can enable telemetry to be sent by using [Enable-PnPPowerShellTelemetry](../cmdlets/Enable-PnPPowerShellTelemetry.md). - -## By setting an environment variable -To disable telemetry, set the `PNPPOWERSHELL_DISABLETELEMETRY` environment variable to `true`, i.e. by using `$env:PNPPOWERSHELL_DISABLETELEMETRY=$true`. Remove the entry again or set it to `false` to enable telemetry to be sent again. - -## By adding a file in your user profile folder -Alternatively, you can create an empty file called `.pnppowershelltelemetry` inside your home directory (`$env:UserProfile` on Windows, `$env:HOME` on Linux) not needing any content inside of the file to disable telemetry. Remove the file again to enable telemetry to be sent. \ No newline at end of file +The telemetry PnP PowerShell cmlets [Get-PnPPowerShellTelemetryEnabled](../cmdlets/Get-PnPPowerShellTelemetryEnabled.md), [Disable-PnPPowerShellTelemetry](../cmdlets/Disable-PnPPowerShellTelemetry.md) and [Enable-PnPPowerShellTelemetry](../cmdlets/Enable-PnPPowerShellTelemetry.md) have been marked as obsolete in version 3.4.2. They will throw a warning when used and will no longer function, but are being kept in the v3 releases for backwards compatibility so existing scripts using them will not break. In version 4.0.0 onwards, these cmdlets have been removed entirely as they no longer serve purpose. \ No newline at end of file diff --git a/src/ALC/ApplicationInsights.cs b/src/ALC/ApplicationInsights.cs deleted file mode 100644 index 7f05781c79..0000000000 --- a/src/ALC/ApplicationInsights.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Microsoft.ApplicationInsights; -using System.Collections.Generic; - -namespace PnP.PowerShell.ALC -{ - /// - /// Azure Application Insights Telemetry Client to allow for usage tracking - /// - public class ApplicationInsights - { - /// - /// Instance of the TelemetryClient to use to report back statistical data - /// - private TelemetryClient _telemetryClient; - - /// - /// Information to provide with each telemetry log entry - /// - private static Dictionary telemetryProperties; - - /// - /// Initializes a new instance of the ApplicationInsights telemetry - /// - /// Version of SharePoint Online to which a connection has been established - /// Version of the server to which a connection has been established - /// Information on what method has been used to establish a connection - /// The PnP PowerShell version in use - /// The operating system on which PnP PowerShell is being used - public void Initialize(string serverLibraryVersion, string serverVersion, string initializationType, string assemblyVersion, string operatingSystem, string psVersion = "") - { - // Retrieve an instance of the telemetry client to use - _telemetryClient = TelemetryClientFactory.GetTelemetryClient(); - - // Define the base set of information to log with each trackable event in Azure Application Insights - if (telemetryProperties == null) - { - telemetryProperties = new Dictionary - { - { "ServerLibraryVersion", serverLibraryVersion }, // Version of SharePoint Online to which a connection has been established - { "ServerVersion", serverVersion }, // Version of the server to which a connection has been established - { "ConnectionMethod", initializationType.ToString() }, // Information on what method has been used to establish a connection - { "Version", assemblyVersion }, // The PnP PowerShell version in use - { "Platform", "SPO" }, // Platform to which the connection has been made - { "OperatingSystem", operatingSystem}, // The operating system on which PnP PowerShell is being used - { "PSVersion", psVersion} - }; - } - } - - /// - /// Sends information to Azure Application Insights to track an event - /// - /// Name of the PnP PowerShell cmdlet that is being executed - /// Additional information on the cmdlet being executed. Optional. - public void TrackEvent(string cmdletName, Dictionary properties = null) - { - // Take the base set of information to log - var localProps = telemetryProperties; - - // If additional properties have been provided to log, add them to the base set of information to log - if (properties != null) - { - foreach (var prop in properties) - { - localProps.Add(prop.Key, prop.Value); - } - } - - // Create the logging entry - _telemetryClient.TrackEvent(cmdletName, localProps); - } - } -} \ No newline at end of file diff --git a/src/ALC/PnP.PowerShell.ALC.csproj b/src/ALC/PnP.PowerShell.ALC.csproj deleted file mode 100644 index a6f03847bf..0000000000 --- a/src/ALC/PnP.PowerShell.ALC.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net8.0 - true - Debug;Release;DebugLocal - - - - - - - diff --git a/src/ALC/TelemetryClient.cs b/src/ALC/TelemetryClient.cs deleted file mode 100644 index ef8d536b1c..0000000000 --- a/src/ALC/TelemetryClient.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using Microsoft.ApplicationInsights.Extensibility; -using Microsoft.ApplicationInsights; - -namespace PnP.PowerShell.ALC -{ - /// - /// Telemetry client instance implemented as a singleton to avoid memory leaks - /// - public static class TelemetryClientFactory - { - /// - /// Singleton instance of the TelemetruClient - /// - private static TelemetryClient _telemetryClient; - - /// - /// Gets an instance of the telemetry client to use. Creates a new instance if not already present in memory or otherwise re-uses the one available in memory. - /// - /// TelemetryClient instance - public static TelemetryClient GetTelemetryClient() - { - // If we already have an instance, return it - if (_telemetryClient != null) return _telemetryClient; - - // Create a new telemetry instance - TelemetryConfiguration config = TelemetryConfiguration.CreateDefault(); - - _telemetryClient = new TelemetryClient(config); - config.ConnectionString = "InstrumentationKey=a301024a-9e21-4273-aca5-18d0ef5d80fb;IngestionEndpoint=https://westeurope-4.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/;ApplicationId=0224718b-f8f5-4252-bc7c-616e9a1adc1a"; - _telemetryClient.Context.Cloud.RoleInstance = "PnPPowerShell"; - _telemetryClient.Context.Device.OperatingSystem = Environment.OSVersion.ToString(); - - return _telemetryClient; - } - } -} \ No newline at end of file diff --git a/src/Commands/Base/DisablePowerShellTelemetry.cs b/src/Commands/Base/DisablePowerShellTelemetry.cs index c615192d07..ac4f6191da 100644 --- a/src/Commands/Base/DisablePowerShellTelemetry.cs +++ b/src/Commands/Base/DisablePowerShellTelemetry.cs @@ -4,7 +4,8 @@ namespace PnP.PowerShell.Commands.Base { [Cmdlet(VerbsLifecycle.Disable, "PnPPowerShellTelemetry")] - [Attributes.ApiPermissionsNotRequired(Remarks = "This cmdlet updates a local file, an environment variable and the telemetry setting of the current connection, and performs no request.")] + [Obsolete("Disable-PnPPowerShellTelemetry is deprecated and will be removed in the next release.")] + [Attributes.ApiPermissionsNotRequired(Remarks = "This cmdlet performs no request.")] public class DisablePowerShellTelemetry : PnPSharePointCmdlet { [Parameter(Mandatory = false)] @@ -12,27 +13,7 @@ public class DisablePowerShellTelemetry : PnPSharePointCmdlet protected override void ProcessRecord() { - var userFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - var telemetryFile = System.IO.Path.Combine(userFolder, ".pnppowershelltelemetry"); - if (Force || ShouldContinue("Do you want to disable telemetry for PnP PowerShell?", Properties.Resources.Confirm)) - { - System.IO.File.WriteAllText(telemetryFile, "disallow"); - Environment.SetEnvironmentVariable("PNPPOWERSHELL_DISABLETELEMETRY", "true"); - if (Connection != null) - { - Connection.ApplicationInsights = null; - } - WriteObject("Telemetry disabled"); - } - else - { - var enabled = false; - if (System.IO.File.Exists(telemetryFile)) - { - enabled = System.IO.File.ReadAllText(telemetryFile).ToLower() == "allow"; - } - WriteObject($"Telemetry setting unchanged: currently {(enabled ? "enabled" : "disabled")}"); - } + WriteObject("Telemetry disabled"); } } } diff --git a/src/Commands/Base/EnablePowerShellTelemetry.cs b/src/Commands/Base/EnablePowerShellTelemetry.cs index ddba6d9ce5..04a1691ab6 100644 --- a/src/Commands/Base/EnablePowerShellTelemetry.cs +++ b/src/Commands/Base/EnablePowerShellTelemetry.cs @@ -4,7 +4,8 @@ namespace PnP.PowerShell.Commands.Base { [Cmdlet(VerbsLifecycle.Enable, "PnPPowerShellTelemetry")] - [Attributes.ApiPermissionsNotRequired(Remarks = "This cmdlet updates a local file, an environment variable and the telemetry setting of the current connection, and performs no request.")] + [Obsolete("Enable-PnPPowerShellTelemetry is deprecated and will be removed in the next release.")] + [Attributes.ApiPermissionsNotRequired(Remarks = "This cmdlet performs no request.")] public class EnablePowerShellTelemetry : PnPSharePointCmdlet { [Parameter(Mandatory = false)] @@ -12,24 +13,7 @@ public class EnablePowerShellTelemetry : PnPSharePointCmdlet protected override void ProcessRecord() { - var userFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - var telemetryFile = System.IO.Path.Combine(userFolder, ".pnppowershelltelemetry"); - if (Force || ShouldContinue("Do you want to enable telemetry for PnP PowerShell?", Properties.Resources.Confirm)) - { - System.IO.File.WriteAllText(telemetryFile, "allow"); - Environment.SetEnvironmentVariable("PNPPOWERSHELL_DISABLETELEMETRY", "false"); - Connection?.InitializeTelemetry(Connection.Context, Connection.InitializationType); - WriteObject("Telemetry enabled"); - } - else - { - var enabled = false; - if (System.IO.File.Exists(telemetryFile)) - { - enabled = System.IO.File.ReadAllText(telemetryFile).ToLower() == "allow" || Environment.GetEnvironmentVariable("PNPPOWERSHELL_DISABLETELEMETRY").Equals("false", StringComparison.InvariantCultureIgnoreCase); - } - WriteObject($"Telemetry setting unchanged: currently {(enabled ? "enabled" : "disabled")}"); - } + WriteObject("Telemetry no longer available"); } } } diff --git a/src/Commands/Base/GetPowerShellTelemetryEnabled.cs b/src/Commands/Base/GetPowerShellTelemetryEnabled.cs index a90f3fcddd..162b833b27 100644 --- a/src/Commands/Base/GetPowerShellTelemetryEnabled.cs +++ b/src/Commands/Base/GetPowerShellTelemetryEnabled.cs @@ -1,15 +1,17 @@ -using System.Management.Automation; +using System; +using System.Management.Automation; namespace PnP.PowerShell.Commands.Base { [Cmdlet(VerbsCommon.Get, "PnPPowerShellTelemetryEnabled")] + [Obsolete("Get-PnPPowerShellTelemetryEnabled is deprecated and will be removed in the next release.")] [OutputType(typeof(bool))] - [Attributes.ApiPermissionsNotRequired(Remarks = "This cmdlet reports a local setting of the current connection and performs no request.")] + [Attributes.ApiPermissionsNotRequired(Remarks = "This cmdlet performs no request.")] public class GetPowerShellTelemetryEnabled : PnPSharePointCmdlet { protected override void ProcessRecord() { - WriteObject(Connection.ApplicationInsights != null); + WriteObject(false); } } } \ No newline at end of file diff --git a/src/Commands/Base/PnPAssemblyLoadContext.cs b/src/Commands/Base/PnPAssemblyLoadContext.cs index 861b3fbd3f..afd2677127 100644 --- a/src/Commands/Base/PnPAssemblyLoadContext.cs +++ b/src/Commands/Base/PnPAssemblyLoadContext.cs @@ -9,8 +9,8 @@ namespace PnP.PowerShell.Commands.Base /// /// A dedicated that owns the complete private dependency /// graph shipped with PnP PowerShell (PnP.Framework, PnP.Core, PnP.Core.Auth, PnP.Core.Admin, - /// the CSOM libraries, Microsoft.Extensions.*, Microsoft.Identity.*, Microsoft.ApplicationInsights, - /// PnP.PowerShell.ALC, Newtonsoft.Json, AngleSharp, and so on). + /// the CSOM libraries, Microsoft.Extensions.*, Microsoft.Identity.*, Newtonsoft.Json, + /// AngleSharp, and so on). /// /// The purpose of this context is full isolation. By overriding to probe /// our own dependency folder first, every assembly loaded here - and, crucially, every transitive diff --git a/src/Commands/Base/PnPConnectedCmdlet.cs b/src/Commands/Base/PnPConnectedCmdlet.cs index 1b3b535b1f..c7ad159f54 100644 --- a/src/Commands/Base/PnPConnectedCmdlet.cs +++ b/src/Commands/Base/PnPConnectedCmdlet.cs @@ -31,12 +31,6 @@ protected void BeginProcessing(bool skipConnectedValidation) Connection = PnPConnection.Current; } - // Track the execution of the cmdlet in Azure Application Insights - if (Connection != null && Connection.ApplicationInsights != null) - { - Connection.ApplicationInsights.TrackEvent(MyInvocation.MyCommand.Name); - } - // Check if we should ensure that we are connected if (skipConnectedValidation) return; diff --git a/src/Commands/Base/PnPConnection.cs b/src/Commands/Base/PnPConnection.cs index 7d906efd33..baa87584f4 100644 --- a/src/Commands/Base/PnPConnection.cs +++ b/src/Commands/Base/PnPConnection.cs @@ -5,7 +5,6 @@ using PnP.Framework; using PnP.Framework.Diagnostics; using PnP.Framework.Utilities.Context; -using PnP.PowerShell.ALC; using PnP.PowerShell.Commands.Enums; using PnP.PowerShell.Commands.Model; using PnP.PowerShell.Commands.Utilities; @@ -102,11 +101,6 @@ internal PnPContext PnPContext /// public string ClientSecret { get; protected set; } - /// - /// Azure Application Insights instance to provide telemetry - /// - public ApplicationInsights ApplicationInsights { get; set; } - /// /// Url of the SharePoint Online site to connect to /// @@ -802,8 +796,6 @@ private PnPConnection(ClientContext context, string pnpVersionTag, InitializationType initializationType) { - InitializeTelemetry(context, initializationType); - var connectionMethod = ConnectionMethod.Credentials; if (initializationType == InitializationType.AzureADWorkloadIdentity) { @@ -960,59 +952,9 @@ public static bool IsTenantAdminSite(ClientRuntimeContext clientContext) } } - internal void InitializeTelemetry(ClientContext context, InitializationType initializationType) - { - var userProfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - var telemetryFile = Path.Combine(userProfile, ".pnppowershelltelemetry"); - - var enableTelemetry = true; - if (Environment.GetEnvironmentVariable("PNP_DISABLETELEMETRY") != null) - { - enableTelemetry = false; - } - // We have old systems to disable telemetry. - // If telemetry should be enabled is based on: - // a. The environmentvariable not having been set OR having been set and having the value false - // AND - // b. The telemetry file not existing OR existing and having the word allow in it - if (enableTelemetry == true) - { - enableTelemetry = ((Environment.GetEnvironmentVariable("PNPPOWERSHELL_DISABLETELEMETRY") == null || Environment.GetEnvironmentVariable("PNPPOWERSHELL_DISABLETELEMETRY").Equals("false", StringComparison.InvariantCultureIgnoreCase)) && - (!System.IO.File.Exists(telemetryFile) || System.IO.File.ReadAllText(telemetryFile).Equals("allow", StringComparison.InvariantCultureIgnoreCase))); - } - // Load Application Insights if telemetry should be enabled - if (enableTelemetry) - { - var serverLibraryVersion = ""; - var serverVersion = ""; - if (context != null) - { - try - { - if (context.ServerLibraryVersion != null) - { - serverLibraryVersion = context.ServerLibraryVersion.ToString(); - } - if (context.ServerVersion != null) - { - serverVersion = context.ServerVersion.ToString(); - } - } - catch { } - } - - ApplicationInsights = new ApplicationInsights(); - var coreAssembly = Assembly.GetExecutingAssembly(); - var operatingSystem = Utilities.OperatingSystem.GetOSString(); - - ApplicationInsights.Initialize(serverLibraryVersion, serverVersion, initializationType.ToString(), ((AssemblyFileVersionAttribute)coreAssembly.GetCustomAttribute(typeof(AssemblyFileVersionAttribute))).Version.ToString(), operatingSystem, PSUtility.PSVersion); - ApplicationInsights.TrackEvent("Connect-PnPOnline"); - } - } - private static string PnPPSVersionTag => (PnPPSVersionTagLazy.Value); - private static readonly Lazy PnPPSVersionTagLazy = new Lazy( + private static readonly Lazy PnPPSVersionTagLazy = new( () => { var coreAssembly = Assembly.GetExecutingAssembly(); diff --git a/src/Commands/Base/PnPPowerShellModuleInitializer.cs b/src/Commands/Base/PnPPowerShellModuleInitializer.cs index 8cfad1438c..f5a58291a2 100644 --- a/src/Commands/Base/PnPPowerShellModuleInitializer.cs +++ b/src/Commands/Base/PnPPowerShellModuleInitializer.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Management.Automation; using System.Reflection; @@ -76,6 +77,7 @@ static PnPPowerShellModuleInitializer() /// resolver is active before cmdlet discovery forces PnP.Framework/PnP.Core to load. Also wired as a /// for defense in depth. Safe to call multiple times. /// + [SuppressMessage("Usage", "CA2255:The ModuleInitializer attribute should not be used in libraries", Justification = "PowerShell loads this binary module into a host process; the resolver must be registered before cmdlet discovery loads private dependencies.")] [ModuleInitializer] public static void EnsureDependencyResolverRegistered() { diff --git a/src/Commands/PnP.PowerShell.Release.csproj b/src/Commands/PnP.PowerShell.Release.csproj index 225cb1a18e..6a16cb0fde 100644 --- a/src/Commands/PnP.PowerShell.Release.csproj +++ b/src/Commands/PnP.PowerShell.Release.csproj @@ -50,7 +50,6 @@ - @@ -92,4 +91,11 @@ Resources.resx + + + + + + + diff --git a/src/Commands/PnP.PowerShell.csproj b/src/Commands/PnP.PowerShell.csproj index b5f3365cc4..eb84d817e0 100644 --- a/src/Commands/PnP.PowerShell.csproj +++ b/src/Commands/PnP.PowerShell.csproj @@ -68,8 +68,6 @@ - - @@ -137,4 +135,11 @@ Resources.resx + + + + + + + diff --git a/src/Commands/_debug/debug.ps1 b/src/Commands/_debug/debug.ps1 index 7321588b9a..52d3ccf871 100644 --- a/src/Commands/_debug/debug.ps1 +++ b/src/Commands/_debug/debug.ps1 @@ -3,7 +3,7 @@ $env:PNPPOWERSHELL_UPDATECHECK = "Off" $ProjectPath = $PSScriptRoot | Split-Path -Parent $BinPath = "$ProjectPath\bin\Debug" -$dlls = @("PnP.PowerShell.ALC.dll", "PnP.PowerShell.dll") +$dlls = @("PnP.PowerShell.dll") $netversion = "net8.0" $BinPath = "$BinPath\$netversion" diff --git a/src/PnP.PowerShell.sln b/src/PnP.PowerShell.sln index dcbdf9907b..c4990e554c 100644 --- a/src/PnP.PowerShell.sln +++ b/src/PnP.PowerShell.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 17.4.33213.308 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PnP.PowerShell", "Commands\PnP.PowerShell.csproj", "{F91159F1-31F8-47CF-B546-9487F9EF8426}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PnP.PowerShell.ALC", "ALC\PnP.PowerShell.ALC.csproj", "{546A8F8C-AD8A-488D-98DB-5AB25CF9558B}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -20,12 +18,6 @@ Global {F91159F1-31F8-47CF-B546-9487F9EF8426}.DebugLocal|Any CPU.Build.0 = Debug|Any CPU {F91159F1-31F8-47CF-B546-9487F9EF8426}.Release|Any CPU.ActiveCfg = Release|Any CPU {F91159F1-31F8-47CF-B546-9487F9EF8426}.Release|Any CPU.Build.0 = Release|Any CPU - {546A8F8C-AD8A-488D-98DB-5AB25CF9558B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {546A8F8C-AD8A-488D-98DB-5AB25CF9558B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {546A8F8C-AD8A-488D-98DB-5AB25CF9558B}.DebugLocal|Any CPU.ActiveCfg = DebugLocal|Any CPU - {546A8F8C-AD8A-488D-98DB-5AB25CF9558B}.DebugLocal|Any CPU.Build.0 = DebugLocal|Any CPU - {546A8F8C-AD8A-488D-98DB-5AB25CF9558B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {546A8F8C-AD8A-488D-98DB-5AB25CF9558B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Tests/PnP.PowerShell.Tests.csproj b/src/Tests/PnP.PowerShell.Tests.csproj index b77efda6f9..77efd71c95 100644 --- a/src/Tests/PnP.PowerShell.Tests.csproj +++ b/src/Tests/PnP.PowerShell.Tests.csproj @@ -31,7 +31,6 @@ - From cf3da545f6a237a64ea8cfdbed1dfb33e54dccd9 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sat, 5 Sep 2026 10:33:04 +0200 Subject: [PATCH 2/5] Update CHANGELOG for telemetry removal and deprecation Removed telemetry functionality in PnP PowerShell and marked related cmdlets as deprecated. Updated changelog to reflect these changes and provided details on backward compatibility. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8d691c065..35042d5dc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added ### Changed -- Marked `Get-PnPPowerShellTelemetryEnabled`, `Enable-PnPPowerShellTelemetry` and `Disable-PnPPowerShellTelemetry` as deprecated. These cmdlets will be removed in the next release. +- Telemetry in PnP PowerShell has been removed due to the costs of collecting the data didn't outweigh the benefits to the PnP PowerShell team to have insights into its usage. The involved cmdlets `Get-PnPPowerShellTelemetryEnabled`, `Enable-PnPPowerShellTelemetry` and `Disable-PnPPowerShellTelemetry` have been marked as deprecated and no longer function, but will stay in v3 for backwards compatibility with existing scripts. These cmdlets will be removed in the next v4 release. All versions of PnP PowerShell will no longer be able to submit telemetry. You might see background requests for this failing. This will not interfear with the normal execution of your PowerShell script. [#5460](https://github.com/pnp/powershell/pull/5460) ### Fixed - Using UPNs with an apostrophe in it not working with `Remove-PnPUserProfile`, `Export-PnPUserProfile`, `Export-PnPUserInfo`, and `Remove-PnPUserInfo`. The apostrophe is now escaped in the API request. [#5459](https://github.com/pnp/powershell/pull/5459) From ab86399685318541138b72293b69c5e98c0187d9 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sat, 5 Sep 2026 10:34:14 +0200 Subject: [PATCH 3/5] Update deprecation notice for Disable-PnPPowerShellTelemetry --- documentation/Disable-PnPPowerShellTelemetry.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/Disable-PnPPowerShellTelemetry.md b/documentation/Disable-PnPPowerShellTelemetry.md index 6643e5a8a3..285d2c98c4 100644 --- a/documentation/Disable-PnPPowerShellTelemetry.md +++ b/documentation/Disable-PnPPowerShellTelemetry.md @@ -10,7 +10,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Disable-PnPPowerShellTe # Disable-PnPPowerShellTelemetry > [!WARNING] -> This cmdlet is deprecated and will be removed in the next release. +> This cmdlet is deprecated and will be removed in the v4 release. ## SYNOPSIS Disables sending of telemetry data. @@ -63,4 +63,4 @@ Accept wildcard characters: False ``` ## RELATED LINKS -[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) From 78122d8004b082789ff3e2286431cb1857edca1d Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sat, 5 Sep 2026 10:34:34 +0200 Subject: [PATCH 4/5] Update deprecation notice for telemetry cmdlet --- documentation/Enable-PnPPowerShellTelemetry.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/Enable-PnPPowerShellTelemetry.md b/documentation/Enable-PnPPowerShellTelemetry.md index fee91aa5e3..b33b6d31d0 100644 --- a/documentation/Enable-PnPPowerShellTelemetry.md +++ b/documentation/Enable-PnPPowerShellTelemetry.md @@ -10,7 +10,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Enable-PnPPowerShellTel # Enable-PnPPowerShellTelemetry > [!WARNING] -> This cmdlet is deprecated and will be removed in the next release. +> This cmdlet is deprecated and will be removed in the v4 release. ## SYNOPSIS Enables sending of telemetry data. @@ -63,4 +63,4 @@ Accept wildcard characters: False ``` ## RELATED LINKS -[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) From 1a4aa1cbb665cedbb8b28df934285723abf4af41 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sat, 5 Sep 2026 10:34:50 +0200 Subject: [PATCH 5/5] Update deprecation notice for Get-PnPPowerShellTelemetryEnabled --- documentation/Get-PnPPowerShellTelemetryEnabled.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/Get-PnPPowerShellTelemetryEnabled.md b/documentation/Get-PnPPowerShellTelemetryEnabled.md index 83e6617a54..45181585b1 100644 --- a/documentation/Get-PnPPowerShellTelemetryEnabled.md +++ b/documentation/Get-PnPPowerShellTelemetryEnabled.md @@ -10,7 +10,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Get-PnPPowerShellTeleme # Get-PnPPowerShellTelemetryEnabled > [!WARNING] -> This cmdlet is deprecated and will be removed in the next release. +> This cmdlet is deprecated and will be removed in the v4 release. ## SYNOPSIS Returns true if the PnP PowerShell Telemetry has been enabled.