Skip to main content

r/PowerShell


Stop using [System]
Stop using [System]
Script Sharing

I'm getting old enough that my fingers hate my lifetime of programming.

I'll save a few keystrokes where I can.

There's something simple most people don't seem to know about PowerShell syntax.

It saves seven characters of typing every you use this, and runs a tiny bit faster.

You never need to specify stuff is in the [System] namespace.

Stop Using [System]

.NET is a huge framework with tons of useful stuff in it. There's a lot of stuff in the System namespaces. Built-in framework functionality often exists in one of the many namespaces in System.

By the time PowerShell was being built, it was pretty clear that leveraging .NET was worth it, and that most people wouldn't want to type six to seven more characters every time.

So, since PowerShell v1, you haven't had to.

You can omit the [System] in any type in any system namespace

So instead of:

 [system.collections.generic.list[string]]

We can write:

 [collections.generic.list[string]]

Instead of:

 [System.Collections.IDictionary]

We can write:

 [Collections.IDictionary]

This is true for every system type. On my machine, there are 4722 public types in the system namespace. That's 33054 characters I will never have to type.

It makes scripts shorter and simpler to read.

Also, when PowerShell resolves types, it checks for the shorter names first. This saves a very tiny amount of time in each of your scripts. (I was corrected)

Yet, sadly, I see the system namespace everywhere in people's scripts.

I beg of you all:

  • Save your fingers

  • Make scripts shorter

Stop Using [System]


Advertisement: All eyes on Wegovy® pill. Talk to your prescriber today.
All eyes on Wegovy® pill. Talk to your prescriber today.

See the following links for: Medication Guide & Safety Information

media poster


Made a PowerShell script that strips telemetry, ads, and forced AI out of Windows 11 (and nothing else)
Made a PowerShell script that strips telemetry, ads, and forced AI out of Windows 11 (and nothing else)
Script Sharing

I switched back to Windows from Linux recently and the amount of telemetry, ad "suggestions," and forced Copilot/Recall stuff drove me up the wall. So I put the fixes I kept applying by hand into one script.

It does three things and nothing more:

Privacy / telemetry

  • Disables the DiagTrack "Connected User Experiences and Telemetry" service + sets telemetry policy to 0

  • Kills the advertising ID, tailored experiences, app-launch tracking, and activity history

  • Turns off the Start/Settings/lock-screen "suggested content" ads and the auto-installer that drops promo apps (Candy Crush etc.) onto fresh installs

Forced AI

  • Turns off Windows Copilot, Recall, and Click to Do

  • Removes Bing/Cortana web results from Start search

Obvious bloat

  • Removes a short list of preinstalled junk apps (Bing News/Weather, Solitaire, Clipchamp, Get Help, Feedback Hub, Maps, People, Office Hub, the new Outlook, Power Automate, Dev Home, Cortana). The list is right at the top of the script, edit it to taste.

Limitations / what to know:

  • Windows 10/11 only. On older builds the AI/Recall keys just do nothing (harmless).

  • Works best on Pro/Enterprise. On Home, Windows clamps telemetry to "Required" instead of fully off, and may ignore the consumer-features policy. Everything else still applies.

  • It uses the official Windows toggles/policies — it's not a firewall or hosts-file block. If you want network-level telemetry blocking on top, pair it with something like a Pi-hole or a hosts list.

  • Some changes need a sign-out or reboot to fully kick in (taskbar/search/Copilot button).

  • App removal is current-user only and every app is reinstallable from the Store, so nothing's permanent.

  • Reverting: re-enable the two services (DiagTrack, dmwappushservice) and delete the keys it set. I might add an -Undo flag later.

What it does NOT do: it doesn't touch your installed programs, files, games, drivers, or your language/region/keyboard. (I'm Danish — it leaves æ ø å completely alone. That was a hard requirement for me.)

I'm not piping anything into iex for you — copy the script straight from the repo, read it, then run it yourself in an admin PowerShell. It's one file, plain PowerShell, no binaries, no network calls.

Repo: https://github.com/oscarmeldgaard/Windows-Privacy-Debloat

Read every line before you run it. Not trying to reinvent O&O ShutUp10 or Win11Debloat — this is just the lean subset I actually wanted, in a file you can read in two minutes. Feedback and PRs welcome.


Simple Splatting and the GitHub CLI
Simple Splatting and the GitHub CLI
Script Sharing

Brevity may be the soul of wit, and I may be bad at it.

Let's try to make a quick post about a little daily PowerShell timesaver: splatting the GitHub CLI.

I'm going to show you how you can save typing and time with the GitHub CLI.

What is Splatting?

Splatting is a simple technique in PowerShell. It lets you pass multiple parameters. It's been there since PowerShell version 2. This is old, consistent technique.

Most people are used to splatting a dictionary, like:

# You can splat a dictionary
$MyId = @{id=$pid}
Get-Process @MyId

This is a cool and useful technique, and most people overlook the other half of splatting:

# You can splat a list
$allIssues = @('--state', 'all', '--limit, '2kb')
gh issue list @allIssues

The Trick

You just saw it.

There are millions of apps you could use this trick with.

I just happen to use the github cli on most days.

You're trading typing all of those arguments for typing a shorter string.

It saves seconds every time you use it.

And it's one simple line.

You can stick it in your profile and every time you're using PowerShell, you'll have those variables to use.

You can just type this sort of trick in if you find yourself using the same parameters.

Think of it as a preset of parameters. Because that's basically what it is.

Multiple Splats

It's important to know that you can do multiple splats.

Here's a simple example:

$bug = @('--label', 'bug')
$assignMe = @('--assignee', '@me')

gh issue create --title 'Some Issue' --body 'Some problem' @assignMe @bug

This would create a bug.

Let's make another, longer one:

# Get issue information as json.
$IssueAsJson= @('--json', (
    'assignees','author','body','closed','closedAt',
    'closedByPullRequestsReferences','comments','createdAt',
    'isPinned','labels','milestone','number','reactionGroups',
    'state','stateReason','title','updatedAt','url' -join ','    
))

$allIssues = @('--state', 'all', '--limit, '2kb')
$IssueList = gh issue list @allIssues @issueAsJson | ConvertFrom-Json
$issueList

If you run this, you

  • List all of the issues from a repo as json

  • Convert them from json into objects

Feel free to copy/paste these tricks into your profile. They're handy!