Most of the Windows 10 telemetry settings rely on registry settings, services, and scheduled tasks. The PowerShell script introduced in this post allows you disable Windows 10 telemetry.

Alex Chaika

Alex Chaika is a Microsoft Certified Solution Expert (MCSE) with more than 15 years of experience in IT systems engineering. He currently focuses on PowerShell and VMware PowerCLI.

It is important to note that that this script does not remove all Windows 10 telemetry. However, you can use the script to add more registry keys and disable services or scheduled tasks related to telemetry.

Privacy Options in Windows 10

Privacy Options in Windows 10

Now I’ll go line by line through this script.

Function ChangeReg {

Because more than one registry key needs modification, I decided to write this part as a function. The function accepts the following parameters:

$RegKey – represents the registry

$Value –name of the registry entry

$SvcName – name of the service

$CheckValue – initial value of the registry entry

$SetData – desired value of the registry entry

This section informs the user what the script is currently doing using the Write-Host cmdlet. Then it checks if the registry key that we have to change exists using Test-Path. If not, I create this key, spitting the original $RegKey value into the parent and leaf with the help of the Split-Path cmdlet. I’m doing this while bearing in mind that a lot of Windows services are enabled by default but don't have registry keys or values for disabling them. This seems to be true for some telemetry services as well.

Now I need to check whether the registry entry that is responsible for disabling a particular telemetry option already exists. I did this using a try-catch block to avoid errors that the Get-ItemProperty cmdlet would generate if the item I’m trying to read does not exist. To accomplish this, I have to set $ErrorActionPreference to 'Stop' before the try clause because try-catch only reacts to fatal errors. [System.Management.Automation.PSArgumentException] is not one of them. Thus, I ensure that any error is considered fatal using the $ErrorActionPreference variable.

If the registry entry exists, I use an if-statement to check whether the value of this entry equals one, which means that the corresponding telemetry service is enabled. In this case, I let the user know that this particular telemetry option is enabled and that it is going to be disabled. Then I set the registry entry value to $SetData, which disables the telemetry option.

The second if-statement verifies whether the value was changed successfully and then informs the user that it was. The catch statement comes into play if there was an exception, which means that the registry entry does not exist. If this happens, I create a new entry using the New-ItemProperty cmdlet and assign the value that disables the telemetry option.

As you can see, all this bunch of code does is set the variables to the values that correspond to the most obvious telemetry components and then uses the ChangeReg function to disable them.

Finally, I’m coming to the scheduled tasks that are used for telemetry processes. I store them into a string array. Below is a short description of each task:

SmartScreenSpecific – collects data for Microsoft SmartScreen

ProgramDataUpdater – collects program telemetry information if opted-in to the Microsoft Customer Experience Improvement Program (CEIP)

Microsoft Compatibility Appraiser – ollects program telemetry information if opted-in to the CEIP

AitAgent – aggregates and uploads application telemetry information if opted-in to the CEIP

Proxy – collects and uploads Software Quality Management (SQM) data if opted-in to the CEIP

Consolidator – collects and sends usage data to Microsoft (if the user has consented to participate in the CEIP)

KernelCeipTask (Kernel Customer Experience Improvement Program) – collects additional information related to customer experience and sends it to Microsoft (if the user consented to participate in the Windows CEIP)

BthSQM (Bluetooth Customer Experience Improvement Program) – collects Bluetooth-related statistics and information about your machine and sends it to Microsoft (if you have consented to participate in the Windows CEIP). The information received is used to help improve the reliability, stability, and overall functionality of Bluetooth in Windows.

DiskDiagnosticDataCollector (Windows Disk Diagnostic reports) – collects general disk and system information and sends it to Microsoft (if the user users participates in the CEIP)

WinSAT – measures system performance and capabilities

GatherNetworkInfo – collects network information

FamilySafetyMonitor – initializes family safety monitoring and enforcement

FamilySafetyRefresh – synchronizes the latest settings with the family safety website

SQM data sender - sends SQM data to Microsoft

OfficeTelemetryAgentFallBack – initiates the background task for the Office Telemetry Agent that scans and uploads usage and error information for Office solutions

OfficeTelemetryAgentLogOn – initiates the Office Telemetry Agent that scans and uploads usage and error information for Office solutions when a user logs on to the computer

Some tasks might be absent on different Windows 10 installations, so I added a try-catch block to avoid error messages’ being displayed on the console. "$ErrorActionPreference  = 'Stop'" serves the same purpose as it did in the previous case; that is, it ensures that any error calls the Stop instruction.

At the end of the script, I’m trying to disable the task from the $tasks array using the Get-ScheduledTask cmdlet. First, I get the task object, and then, if this operation is successful, I pipe this object to Disable-ScheduledTask. If there is no task with such a name, the catch section generates and catches a Microsoft.PowerShell.Cmdletization.Cim.CimJobException exception . In this case, the message that the task was not found will be produced.

Join the 4sysops PowerShell group!

Your question was not answered? Ask in the forum!


Users who have LIKED this post:

  • avatar
  1. Miroslav 3 years ago



  2. Allan 3 years ago

    Just what I was looking for.


  3. Melvin Backus 3 years ago

    Hmm, seems like there may be a problem with the try/catch on the scheduled tasks. The ones that are present appear to be getting disabled, but the ones that aren't present are generating errors.


    • Author
      Alex Chaika 3 years ago

      I just ran it on couple test VMs with windows 1o. This is the output from one of them:

      However, I've seen such behavior for some scripts before. And usually when you run the try-catch block for the first time it throws an error, but second time it works as it supposed to do.  I have no logical explanation to it.


  4. psc 3 years ago


    Just to alert you to the typo at :

    $ErrorActionPreference = ‘'Stop


  5. Melvin Backus 3 years ago

    I tried running a few times, no change. Even after killing the PS session and starting a new one, just in case things were cached.  I'm getting the error below. Taskname changes but otherwise same stuff. There are about 5 or so in my case.


    • Author
      Alex Chaika 3 years ago

      Well, I just have to admit it does throw and error when ran from PowerShell console. It works perfectly when ran from PowerShell ISE, though. I can't understand why there is such a difference.

      The Set-StrictMode command doesn't change console behavior as well.

      Will continue to investigate.



  6. Melvin Backus 3 years ago

    Since this was just a single machine for now I decided to run it from the ISE. It failed there as well.  In case it makes any difference this is running on 10586.  Powershell version reports as 5/0/10586/494



    • Author
      Alex Chaika 3 years ago

      So, the only way I could get it to work in console is adding the -ErrorAction to each command in the trycatch block. Which is weird, to be honest. Please find the peace of code below:


  7. Jon 3 months ago

    1 - when i copied this script, i got a lot of unicode spaces. don't know how that happened.

    2 - when i run it, i get lots of what looks like dumped registry entries in white text and access errors in red text.

    does this need to be updated?


Leave a reply

Your email address will not be published. Required fields are marked *


© 4sysops 2006 - 2020


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account