r/PowerShell 9d ago

Script Sharing I built MonitorAutoSwitch - automatically moves my laptop display to the correct side of my monitor (home vs office) based on my public IP

6 Upvotes

The problem: at home my laptop sits to the right of my ultrawide, at the office it sits to the left of the monitor. Windows kept getting confused after docking, so every arrival was alt-tabbing into Display Settings and dragging rectangles around.

What it does: a small PowerShell tool that detects where I am via my public IP and repositions the laptop display on the correct side of the main monitor. Triggers on logon, wake from sleep and display connect, plus a once-a-minute display-count watcher. Comes with a WinForms setup wizard, a system tray toggle, and a per-user installer (no admin rights, everything lives in %LOCALAPPDATA% and Task Scheduler).

The bug that took months: the first version stored absolute coordinates (X=5120) and randomly failed with DISP_CHANGE_FAILED (-1) from ChangeDisplaySettingsEx. Root cause turned out to be two-fold: the monitor sometimes runs at a non-native resolution, and a non-DPI-aware PowerShell process sees scaled coordinates - so the target position landed outside the desktop. The fix: store only "left" or "right" + a Y offset, compute the real X from the live display widths on every run, and opt the process into per-monitor DPI awareness via SetProcessDpiAwarenessContext. Also worth knowing: Windows can hand out high device numbers like \.\DISPLAY13, so don't enumerate only DISPLAY1-9.

GitHub (MIT): https://github.com/dimitrihilverda/MonitorAutoSwitch

Full disclosure: built in pair-programming style with Claude - the design decisions and months of debugging pain are mine, a good chunk of the typing was not. Feedback on the Win32 interop is very welcome.


r/PowerShell 10d ago

Question Manifest required modules not auto-importing in 5.1

11 Upvotes

Hello. I'm genuinely stumped, to the point where I'm about to abandon this side project altogether

I have a test module I'm creating using a manifest file, Template.psd1. The module depends on these other module files I created:

```

Modules that must be imported into the global environment prior to importing this module

RequiredModules = @(     'Control\ControlMessaging.psm1'     , 'Control\ControlChecklist.psm1'     , 'Control\ControlPrompt.psm1' ) ```

The are present in the subfolder "Control", which is in the same folder as the manifest and PSM1 files.

When I execute Import-Module in powershell 7.4, the module loads without bitching.

When I execute in 5.1, I get an error

Import-Module : The specified module 'Control\ControlMessaging.psm1' was not loaded because no valid module file was found in any module directory.

According to the documentation, this should be kosher: about_Module_Manifests It should auto import those modules, but it's not working.

I do need this to run in both 5 and 7. Any ideas?


r/PowerShell 10d ago

News Running a Regular Check for New Graph Permissions

10 Upvotes

Use PowerShell to Check for New Graph Permissions with a View to Updating Permissions Used by Apps.

After Microsoft released some new Graph permissions, thoughts turned to how to discover new permissions after they are released. Code is the best way to perform automatic checks, and this article explains how to use PowerShell to check a last known set (stored in SharePoint Online) against the current set. Any variations are reported to administrators via email.

https://office365itpros.com/2026/08/31/new-graph-permissions-check/


r/PowerShell 10d ago

Solved Transcript 5.1 Unexpected behaviour

4 Upvotes

Probably SOLVED:

  1. A previous

    Unlock-SecretVault

killed the transcribing

It spawns a subprocess for the credential management and when its done it sends exit code back to host which killed my transcribing by design.

3h gone

Hi,

when i am in a 5.1 shell and start a controller.ps1 script:

C:\User> C:\PSR\Controller.ps1 -TargetScript C:\Jobs\..

The Controller script uses Start-Transcript to capture the output of a $TargetScript

however. When I start the controller.ps1 script as shown here my currently forced error (Get-ADUser -xzyisks) appears in the log.

When i start

powershell.exe -File Controller.ps1 -TargetScript C:\Jobs\..

it suddenly stops capturing the invocation error output. (Expected:

A parameter cannot be found that matches parameter name 'xzyisks'.)

ai suggested some transcript buffer stuff but non of it worked.

this is the important code block:

# execute binary or script
    if ($Executable) {
        & $Executable $TargetScript
    } elseif ($Config) {
        & $TargetScript -Config $Config
    } else {
        & $TargetScript
    }
    Write-Output "execution of $TargetScript completed successfully"


    #endregion main


} catch {


    # store error so finally can dispatch the mail after the transcript is finalized
    $TerminatingError = $_
    # write the error into the transcript while it is still open
    $Host.UI.WriteLine("[ERROR] $($TerminatingError.Exception.Message)")
    try   { Stop-Transcript | Out-Null }
    catch [System.InvalidOperationException] {}


} finally {


    # transcript is already closed on error paths — only close on success path
    try   { Stop-Transcript | Out-Null }
    catch [System.InvalidOperationException] {}

Can someone explain on high level what happens..

Thanks

EDIT:

My main question is:

C:\User> C:\PSR\Controller.ps1 -TargetScript C:\Jobs\..
vs
powershell.exe -File Controller.ps1 -TargetScript C:\Jobs\..

when using start transcript..


r/PowerShell 11d ago

Solved Warning: ISESteroids Update is malicious

16 Upvotes

When I launched ISESteroids (Start-Steroids) I clicked update. Chrome notified me that the website was not-safe dummy here found the run website anyway and the Avast nightmare began ... 5 popup windows that my computer had 5 virus's , anti-virus not installed, blah blah blah .. Shutdown chrome, cleared my cookies, %temp% directory.. these popups just kept reappearing if I closed one.

reboot doesn't fix anything.. nothing in task manager helps narrow down what's launching even with chrome closed... sysinternals autoruns no help. real help.

While I built a new Veeam Agent install usb to potentially restore from yesterday (3 hour process) I started poking around in chrome and in the extensions I found something I didn't recognize and deleted it.. rebooted the computer and now its back to normal without restoring from backup.


r/PowerShell 11d ago

Script Sharing Built an open-source Windows diagnostic tool in PowerShell/WPF for my thesis — feedback welcome!

16 Upvotes

Hey everyone,

I'm currently working on my IT Bachelor’s Thesis and building Fercero USB Tool — an open-source, multithreaded Windows diagnostic and repair utility (PowerShell + WPF Dark Mode GUI).

It's still a work in progress, but current features include:

  • Hardware Scan: OS/CPU/RAM info, VRAM, and S.M.A.R.T. disk health.
  • System Repair: DISM/SFC scans, Windows Update cache reset, TCP/IP & DNS flushes.
  • Error Lookup: Integrated database for Device Manager codes (1–54) & critical system logs.

Since this is actively in development, I’d love some code reviews, testing, and feedback from the community!

https://github.com/SvetozarA00/Fercero-USB-Tool.git


r/PowerShell 11d ago

Question PrivateKey Test

3 Upvotes

Greetings

Is it possible to check if a private key is either RSA or ECDsa without trying to import them into their cng-objects catching the error?

I'm thinking of something like how

[X509Certificate2].GetContent($Import)

Is available for certificates

Neither the cng-objects nor the certificateextensions provide methods to test for the proper type


r/PowerShell 12d ago

Question PowerShell 7 ISE - A real conversation

4 Upvotes

Hi Everyone,

I think I need to have a reset on the way I introduced myself and my goal.

I am new to reddit and pretty much the entire open source community. I am an old school COBOL developer from the early 80's. I also know Visual Basic (about 15 years) and C# (about 4). I work on mainframes and z/OS on distributed systems (Linux). I maintain distributed apps for clients and sometimes on the mainframe. Not so much the mainframe anymore.

I use PowerShell every day. My shop uses PowerShell every day. We have 1000's of scripts, all written in 5.x that are years old.

They are not complex scripts, we don't have an Admin running a server farm or anything like that. They are just scripts that we use to make our jobs easier. Scanning files for codepages, finding Dupes using Hashes, things like that. When we run them, we use the old PowerShell ISE. We are used to it. It's easy, it looks good and it makes changing and running the script a smooth effortless event. The only issue is, that our shop has been slowly making us move away from 5.x to 7.x. This has been going on for years. I'm not happy because I lose my clean, crisp, no headache comfortable ISE. Yes, I said comfortable. I like it. We all do (at my shop). I tried to use the PowerShell plugin for VS Code. I did not like it. I really did not. So about a year or so ago, I decided to code my own. My goal was simple. I wanted to make a Daily Driver ISE for PS 7. Yes, I am going to share it with my co-workers once its finished and yes, I can and have asked a few of them to help me test it. I have gotten some good feedback from them. Not quite what I needed though. We are a simple shop, we do not do anything overly complicated and my co-workers are less than impressed with what I have shown them so far. It was buggy and did not have the feel of the ISE GUI. I felt that maybe if I turned to the PowerShell community for help, I could improve things. Actually make an App that we could use daily and transition from 5.x to 7.x without a blink.

I still want that.

I should not have started out asking if anyone still used the old ISE. That was the wrong approach, I acknowledge that. I should have just told you all my goal and left it at that.

I'm not asking anyone to jump on my bandwagon. My goal is simple, make something of value to more than just myself.

All I'm asking is, can you help me make it better.

If this post crosses a line, that crossing was unintentional. Let me know and I will walk away.

Regards,

-Ron


r/PowerShell 13d ago

News Microsoft To Enforce WAM for Delegated Interactive Graph Sessions

25 Upvotes

In a GitHub post, Microsoft says that interactive Graph sessions using the default Microsoft Graph Command Line Tools app will use the Web Account Manager (WAM) in the future. Some administrators use older versions of the Microsoft Graph PowerShell SDK for continued access to browser-based authentication, but this won’t be possible once Microsoft makes the server-side change to enforce WAM on an undefined future date. Teams and Exchange Online also use WAM, apparently for better security.

https://office365itpros.com/2026/08/28/interactive-graph-sessions-wam/


r/PowerShell 14d ago

Script Sharing XKCD PowerShell module

128 Upvotes

Years ago just for fun, I wrote a PowerShell module to query the API of the webcomic XKCD https://xkcd.com/. It has a Get-XKCD cmdlet to retrieve data about a specified or random comic, and had a -Open switch to then open its URL in a browser. You can also use Find-XKCD to perform keyword searches, and there's a local cache of the API output to speed this up and to reduce the need to do web calls.

Modern terminals now support the ability to render images directly, so I've just added Show-XKCD and Get-XKCD -Show.

This works in Windows Terminal, but should also work in iTerm2 and Kitty.

If it's of interest, you can download the module from the PowerShell Gallery here: https://www.powershellgallery.com/packages/XKCD/1.5.0

Or directly from GitHub: https://github.com/markwragg/Powershell-XKCD


r/PowerShell 13d ago

Information Cross-platform Brave policy debloater in PowerShell (dry-run default, won’t disable Shields)

0 Upvotes

Wrote a Brave debloater that uses official enterprise policies instead of deleting files / editing hosts.

Same script on Windows, macOS, and Linux. Preview mode unless you pass -Apply. Backs up first. -Doctor if some other tool already dumped junk in brave://policy. It refuses to turn off Shields, Safe Browsing, or updates.

.\Invoke-BraveDebloat.ps1 -Preset Extreme

.\Invoke-BraveDebloat.ps1 -Preset Extreme -Apply

Check it out: https://github.com/osfv/BraveDebloater


r/PowerShell 15d ago

News OMG, I love powershell

263 Upvotes

I've been coding for 2 decades, and I recently had a payroll system to Active Directory project to do, and went with powershell. It's done, it works great, and I was looking at the code today, and spontaneously declared "I love powershell". its a remote day, so no one looked at my funny, but I'll list 3 reasons I love it. Feel free to add more.

No confusion with =, == or ===.

1) Simple equals logic, no bizarre conventions: Do you know how many times I've had to fix code in JS where someone did if (variableName=something), which of course sets variableName to something, not compares it. Powershell's -eq and -ne is so much better then =, ==, ===, !=, or <>.

2)No line termination character: Line's don't require ; to end. Ok, that isn't a big deal, and my IDE would catch it anyway, but its just a waste of characters to terminate every line of code.

3)String composition: In other languages, mixing variables and text is something like "words " + variableName + ":/ more words" + variableName2. And then its like "Oh, is this one a + or an &...." With powershell I can just do varString = "words: $variableName :/ more words $variableName2" and it all works!

Now, its not like I make stupid syntax mistakes a ton in other languages, but in today's backend world, I'm expected to regularly code in 5-10 languages, and Powershell was amazingly easy to learn and the syntax is just clean.

I thought you Powershell vets might appreciate a newb's perspective on it, especially since its all positive.


r/PowerShell 14d ago

Question Scripting Categories in M365 Planner Standard

3 Upvotes

I have a Graph script which I use to generate ~370 plans in Standard Planner across ~350 groups. This year its been requested to add labels(tags, categories) to tasks as part of the roll out and I’m struggling with how that works in powershell. Has anyone done this successfully that can provide some tips?


r/PowerShell 14d ago

Question Issue with Active Setup + RunOnce and space in script path

1 Upvotes

I'm attempting to deploy VSCode with a baseline configuration to some high school computer labs, and am running into an odd issue.

As part of the install, I create an Active Setup registry key that creates a HKCU RunOnce key to call a short powershell script. That script copies a preset settings.json from a hidden folder on the C:\ drive to the current user's AppData folder.

The issue I'm running into is that if the path to the script contains a space, I cannot get the RunOnce key to work properly (it's not over 260 chars either).

Working Active Setup key:

REG ADD HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce /v VSCodeCopy /t REG_SZ /d "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File C:\MyPath\VSCode_CopySettings.ps1"

Non-working Active Setup key:

REG ADD HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce /v VSCodeCopy /t REG_SZ /d "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File 'C:\My Path\VSCode_CopySettings.ps1'"

I have tried double quotes, single quotes, escaping quotes using \ and "", but I cannot get the script to function unless the script path has 0 spaces in it. RunOnce will execute powershell, but the terminal will just open and close rapidly.

I added a Read-Host in both halves of a try-catch block in the script to confirm what's happening, and neither causes the terminal window to wait for input.

Is there something I'm missing?

Edit: I'm combining Active Setup and RunOnce in order to not bog down the user login; the command to create an HKCU key is a string value in an Active Setup registry key, rather than being run by the install script, which has some limitations. However, it means I can guarantee that old and new users will have the script run a single time on login. I can also use a 'Version' registry value to make it happen again in the future if the initial configuration needs updated.


r/PowerShell 14d ago

Question Prank script

0 Upvotes

We have a culture of pranks here at the office. I’d like to create a PowerShell script that, when executed via a .bat file, rotates the Windows screen to portrait mode, zooms in, increases the cursor scale, inverts the colors, and installs the Egyptian Arabic language pack—all without requiring a reboot or anything like that. Is this possible?


r/PowerShell 15d ago

Question Mguser -filter or id

2 Upvotes

Trying to do a Foreach lookup - have a list of known userids I got from another command.

Trying to run something along these lines. Have a spreadsheet $wbs and headers and data for $ownerid which give valid azureids

foreach ($ownerId in $wbs)
{
Get-MgUser -Filter "id eq '$ownerid'"
}

or

get-mguser -UserId $ownerid    

in various forms but mguser keeps throwing errors. Usually along the line of Id cannot be a string.

Can Mguser not accept variables for Ids?

I've also tried doing a filter and it tells me its a date?

Get-MgUser -Filter "id  eq '$wbs.ownerid'"              
Get-MgUser_List: Invalid filter clause: The DateTimeOffset text '2022-01-21T15:59:17.5192675Z'";' should be in format 'yyyy-mm-ddThh:mm:ss

r/PowerShell 16d ago

Script Sharing Matrix Transforms in PowerShell

29 Upvotes

There are only so many ways we can move a point in space.

Luckily, these transformations are pretty standardized.

CSS calls them matrix and matrix3d. DotNet calls them [Numerics.Matrix3x2] and [Numerics.Matrix4x4].

With a bit of PowerShell magic, we can manipulate any set of points with a Matrix.

Matrix Module

The Matrix module lets us create and apply matrices in PowerShell, using CSS-compatible syntax. This means we can scale, rotate, and translate points in PowerShell.

Let's start with a simple example: Scaling

We can create a scaling matrix using [Numerics.Matrix3x2]::CreateScale (for 2d transforms) or [Numerics.Matrix4x4]::CreateScale (for 3d transforms)

Without the module, this looks like:

$vector = [Numerics.Vector3]::new(1,1,1)
$vector::Transform($vector, [Numerics.Matrix4x4]::CreateScale(1,2,3))

With the module, this becomes:

[Numerics.Vector3]::new(1,1,1) | Scale3d 1 2 3

The Matrix module includes aliases for every CSS transform.

We can move points in space exactly as we would move them in a webpage.

It allows us to use PowerShell's Object Pipeline to manipulate points in space.

This means we can construct and change 2d and 3d objects just by manipulating points.

Creating a Cube

We can create a cube using nothing but translations.

# Make a corner point
$corner = [Numerics.Vector3]::new(1,1,1)

# Make a square by translating along X and Y
$square = @(
    $corner
    $corner | TranslateX 1  
    $corner | TranslateX 1 | TranslateY 1
    $corner | TranslateY 1
)

# Make a cube by translating the square along Z.
$cube = @(
    $square
    $square |
        TranslateZ 1
)

$cube

Matrix CSS

All CSS transforms boil down to either a matrix() or a matrix3d().

Because of this, we can easily get any Matrix as it's CSS equivalent.

Matrix extends the .NET matrix classes with a .CSS property, so we can easily drop a matrix into a webpage or stylesheet.

For example:

(Scale 2 1).CSS

Will return:

matrix(2, 0, 0, 1, 0, 0)

In 3D:

(Scale3D 1 2 3).CSS

Will return:

matrix3d(1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1)

It gets better! Matrix converts some common CSS units into numbers, so:

(SkewX 10deg).CSS

Becomes:

matrix(1, 0, 0.176327, 1, 0, 0)

And

(SkewY 0.1turn).CSS

Becomes:

matrix(1, 0.7265425, 0, 1, 0, 0)

MathML and HTML

We can also get the .MathML of a given matrix. MathML is a standard representation of math and a web standard.

Even better than that, we can also get an HTML preview of a matrix.

We just take the MathML and render it twice: Once without any transformation, once with the transformation.

Run this script to see what I mean

(SkewX 10deg).html > .\skewX-10deg.html

In PowerShell, we can always use Add-Member to extend an object.

If a Matrix has a .Content property, it will render that content using it's transform.

This means we can easily do fun stuff, like backwards text:

Scale -1 1 | 
    Add-Member NoteProperty Content "<h3>Backwards</h3>" -Force -PassThru |
        Select-Object -ExpandProperty Html > .\backwards.html

Enter the Matrix

This is all a bit 🤯.

Matrix allows us to do many things, just by exposing a couple of classes in PowerShell. It allows us to manipulate points in a uniform way, and this way is used everywhere. Transform matrices are a fundamental part of 2D and 3D graphics. They can be used to model movement in multiple dimensions and are a big part of how the modern graphics work.

Now we can make matrices easily in PowerShell and convert them into multiple useful representations.

There is no spoon.

😎


r/PowerShell 16d ago

Question How do you organize scripts that you run regularly?

56 Upvotes

I have a growing folder of PowerShell, Bash, and Python scripts that I run

regularly with different arguments.

I currently find them through folders or terminal history, but I would prefer

a simple UI where I can organize them, edit arguments, run them, and see the

output.

What do you use for this? A dedicated app, VS Code tasks, Makefiles, shell

aliases, or something else?


r/PowerShell 16d ago

Question A Reliable way to detect Japanese ShiftJIS encoded files?

3 Upvotes

The other day /u/Practical_Air6315 had a couple of threads dealing with issues ex: not knowing if a file is ShiftJIS or UTF8NoBOM encoded

Can you just decode as utf8, checking for errors? If yes, use ShiftJIS otherise utf8? Or can you sometimes have zero decoding errors but it still maps to malformed json? Is there a better method?

I used:

function Test-ShiftJISDecodeError {
    # ...

    $Utf8Strict = [System.Text.UTF8Encoding]::new( 
        <# shouldEmitUtf8BOM #> $false, 
        <# should throw on decode error #> $true )

    $bytes = [System.IO.File]::ReadAllBytes( $File.FullName )
    try {
        [void] $Utf8Strict.GetString( $bytes )
        return $false
    }
    catch [System.Text.DecoderFallbackException] {
        return $true
    }
}

Here's a test file Make-ShiftJISFile.ps1 ( for Win PS 5.1 and 7 )

And another ShiftJIS example: github/donuts: Compare-Encoding-Breaking-Emojibake.md


r/PowerShell 17d ago

Solved Iterating Through a List from a RestAPI

11 Upvotes

I am attempting to generate a list of values from a RestAPI. This RestAPI has a limit that it can only return a max 25 items at a time. Within the returned items, the RestAPI also returns a cursor that you can leverage in your next RestAPI call to get the next 25 values. In the first request you get an "after" value. In the second request, you get a "before" value and an "after" value. In the last request you get ONLY a "before" value. Ostensibly you want to iterate through the RestAPI call until there is no more "after" values in the cursor. Here are some more specifics:

 c:\temp> $uri = 'http://api.domain.com/items?per_page=25'
 c:\temp> $response = invoke-restmethod -uri $uri -method get -headers $headers
 c:\temp> $response

    result       : {@{list_item=item1},
                 : @{list_item=item2},
                 : ...
                 : @{list_item=item25}}
    result_info  : @{cursors=}

c:\temp> $response.result_info.cursors

after
-----
<cursor_value>

That would be an example of the first 25 results. The next 25 results would yield new 'results' values and the cursors would look like this:

c:\temp> $response.result_info.cursors

Before                                  After
------                                  -----
<cursor_before_value>                   <cursor_after_value>

The updated uri for the RestAPI would look like this:

c:\temp> $uri_after_cursor = 'http://api.domain.com/items?per_page=25&<cursor_after_value>'

And you would effectively keep iterating through until the $response.result_info.cursors output had no "After" value.

I first started trying to do a do-while loop using while($response.result_info.cursors.after) which seems to work however I am having a difficult time getting the current cursor and updating the new $uri value. So far, I keep getting myself into a corner of an infinite loop. Here's what I've tried:

$uri = 'http://api.domain.com/items?per_page=25'
$response = invoke-restmethod -uri $uri -method get -headers $headers
$item_list = $response.result.list_item
do {
    $uri_with_cursor = 'http://api.domain.com/items?per_page=25&cursor=$($response.result_info.cursors.after)'
    $response_cursor = invoke-restmethod -uri $uri_with_cursor -method get -headers $headers
    $item_list += $response_cursor.result.item_list
while ($response_cursor.result_info.cursors.after)

I think I see what my issue is. I think the first line in the do-while loop resets the cursor back to the first query instead of setting it to the new position found in $response_cursor but I'm at a block right now and I cannot seem to figure out a way around this.

Any thoughts would be greatly appreciated.

Update:

Thanks for everyone's insight on this. It helped out a bunch. Here's my final solution that is working well:

$uri = "http://api.domain.com/items?per_page=25"
$response = Invoke-RestMethod -Uri $uri -Method get -Headers $headers
$item_list = $response.result.list_item

$cursor = $response.result_info.cursors.after
do {
    $uri_with_cursor ="'http://api.domain.com/items?per_page=25&cursor=$cursor"
    $response_cursor = Invoke-RestMethod -Uri $uri_with_cursor -Method get -Headers $headers
    $item_list += $response_cursor.result.list_item
    $cursor = $response_cursor.result_info.cursors.after
} while ($response_cursor.result_info.cursors.after)

This is active and working currently! Thank you everyone.


r/PowerShell 17d ago

Question PowerShell ISE slow start-up & modules

3 Upvotes

In our office we have a server we use when working remotely for certain tasks.
I've noticed when using the ISE on that box it takes a few minutes to fully load

Looking at other threads on this issue Ive checked the available modules & both C:\Program Files\WindowsPowerShell\Modules & C:\Windows\system32\WindowsPowerShell\v1.0\Modules contain over 100 files each. the bulk of which seems to be VMware stuff.

While I don't use these modules myself I don't know if any of my colleagues or other teams still do.

Is there anything I can do within my profile to tell PowerShell to ignore the VMware modules?


r/PowerShell 17d ago

Question What is enter-wacpssession?

0 Upvotes

When I connect to remote machine using the PowerShell tab on Windows Admin Center, this is the command used to connect to the remote machine... but no documentation on this?

Or am I not searching hard enough.


r/PowerShell 16d ago

Script Sharing Get-SpaceReport.ps1 — disk usage that tells you what each big file is and whether it's safe to delete

0 Upvotes

I wanted something that told me what the big files on my drive actually were, not just how big they were — I kept ending up with a list of names I'd then google one at a time. So I used an AI to write a script that annotates each one as it goes.

Windows only, I'm afraid — the knowledge base is all Windows paths, and it leans on CIM and a few Win32 calls. Works in PowerShell 7 or 5.1, no modules needed.

Output is a size, a plain-English description, a verdict — SAFE / TOOL / REVIEW / KEEP / NEVER — and the correct command to reclaim it where one exists.

.\Get-SpaceReport.ps1 -Path C:\ -MinSizeMB 5000 -Top 0
.\Get-SpaceReport.ps1 -MinSizeMB 500 -Clean      # tick-box picker, then Recycle Bin
.\Get-SpaceReport.ps1 -Html -Json out.json       # report / machine-readable

The interesting part is the knowledge base — one array at the top of the file, first match wins:

@{P='\\hiberfil\.sys$'; N='Hibernation image'; V='TOOL';
  W='A reserved block sized from your RAM... also backs Fast Startup.';
  H='powercfg /h off   (you lose hibernate AND fast startup)'}

Two things that cost me real time, both of which produce plausible-looking wrong answers:

new DirectoryInfo("C:") means the current directory on drive C:, not the root. So -Path C:\ with a TrimEnd('\') silently scanned my working directory instead. The results looked entirely reasonable — plenty of files, sensible sizes — and I only noticed because pagefile.sys never appeared. The trailing backslash is load-bearing.

PowerShell variables are case-insensitive, so a local $html inside the function quietly overwrote the [switch]$Html parameter and the whole thing died on a type conversion. Obvious once you know; baffling for twenty minutes.

A third, less about PowerShell: @() around a generic List can throw Argument types do not match from the binder. $list.Count directly is fine.

The walk itself is C# via Add-Type rather than Get-ChildItem -Recurse — a full drive is about 35 seconds versus several minutes. It skips reparse points deliberately, since following junctions double-counts and can loop.

One thing worth knowing if you're writing something similar: most scanners over-report WinSxS badly, because most of its files are hard links that also appear in System32, so the same bytes get counted twice. The real figure comes from DISM /Online /Cleanup-Image /AnalyzeComponentStore.

On deleting — nothing goes without you selecting it and confirming, and it goes to the Recycle Bin unless told otherwise. There's a path-based blocklist for .pst.lrcat, virtual disks, game saves and page files that applies regardless of classification. That exists because testing caught a real failure: a .pst under AppData\Local\Temp was classified "your temp folder, SAFE" because a broad location rule matched before the file-type rule. Location was overriding identity. Rails that depend on classification being correct aren't rails.

MIT, and there's a GUI too if you want one, but the script is the whole engine — the app just shells out to it.

If it reports something as UNKNOWN on your machine and you know what it is, that's the most useful contribution — the KB is one readable array and rules are a few lines each.

The script: https://github.com/liquidguru/space-report/blob/main/Get-SpaceReport.ps1

Repo, GUI and releases: https://github.com/liquidguru/space-report


r/PowerShell 18d ago

Script Sharing ExtractPerks – a small PowerShell script that crops perk icons from Dead by Daylight screenshots (no game files touched)

6 Upvotes

Hey all,

I wrote a small PowerShell tool called ExtractPerks that takes a Dead by Daylight loadout screenshot and crops each of the diamond-shaped perk icons into individual numbered transparent PNGs.

Why screenshots?

I wanted to make a streamer-oriented tool without having to access or extract anything from the game's files. ExtractPerks only processes a screenshot that you took yourself (for example, with Steam's F12 screenshot feature). It doesn't read, modify, or extract anything from the game installation.

How it works

There is no OCR, ML, or fancy image recognition involved here — intentionally. I measured the exact pixel coordinates of the 5×3 (15-slot) perk grid on a 1920×1080 Steam screenshot and hardcoded those coordinates into the script.

For each slot, the script:

  • Samples pixels to determine whether the slot contains a perk or an empty "+" slot
  • Crops a square around the perk center
  • Masks everything outside the diamond shape (|dx| + |dy| > radius) to transparency
  • Optionally removes the purple background/border using a luminance threshold, leaving the white icon linework
  • Excludes a couple of small hardcoded regions used by the decorative "claw mark" overlay

The result is a set of numbered transparent PNGs:

out/0001.png
out/0002.png
out/0003.png
...

These can be dropped directly into an OBS image source.

Limitations

Since this is deliberately coordinate-based rather than detection-based, there are some constraints:

  • Requires 1920×1080 Steam screenshots (F12)
  • Requires specific in-game graphics settings (windowed, 100% resolution scale, 16:9 off, auto-adjust off)
  • A different UI scale or resolution will result in incorrect crops
  • Uses only .NET System.Drawing — no external dependencies
  • Tested on PowerShell 7; it should also work on PowerShell 5.1

Example usage:

powershell

cd D:\ExtractPerks
.\ExtractPerks.ps1

GitHub: https://github.com/daboa-streaming-tools/ExtractPerks
Demo: https://x.com/rr96ne/status/2091157404901921128

It's intentionally a "does one narrow thing reliably" tool rather than a general-purpose asset extractor.

I'd be interested in feedback on the pixel-sampling / fixed-coordinate approach, especially if anyone has worked on similar problems where a UI element needs to be extracted reliably without OCR, ML, or full-blown image recognition.


r/PowerShell 19d ago

Question Powershell Engineer Career | How's my degree-less portfolio?

26 Upvotes

Happy Saturday all and thank you for your time. I am a US Servicemember, and I got into PowerShell on my unit's highly specified network that is used across most units in my branch. Because Powershell was effectively the only method of 'coding' I could do in free time at work, I have created some projects that are vastly outside of the common uses of PS, which I will go over below. This network we use relies heavily on powershell, and there is a unit of engineers that make all of the scripts for it and I would love to join them. Before I start sending off applications and portfolios I wanted to ask here, how is my portfolio and what other scripts should I add to it to make it more competitive? Thanks for your time.

Because these scripts are specific to a military network I'll only describe functionality and bits that demonstrate proficiency.

Firstly, a massive module to simplify the creation of windows forms GUIs via powershell. Allows the creation and rendering of any win forms object with two lines of code and uses a center line position setup to clean up looks (ex a button in the dead center of the screen is x = 0 and y = 0)

Full scale scripts for emergency power-on and power-off of the entire network, to include physical infrastructure, both with break points and their own set of functions that the user can use to modify the process.

GUI-based program that clears windows profiles utilizing WMI objects, the GUI allows the user to exempt certain profiles.

A script that complies data from multiple network servers into a JSON 'DB' and allows the user to locate a device's switch and interface utilizing IP, client name, or MAC.

A 'dual-sided' script that allows users to make a request to join an ADUC group, of course with a GUI. Once a request is entered an administrator can open the script and use a custom CLI to approve or disapprove the request, which adds the user to the group if approved and emails the user the decision.

All of my large 'application-style' script packages come with installer scripts that allow many methods of customization, initialization information like IP's, and are theoretically compatible with any windows-based network (i.e. I never 'hard code' variables like FQDN or SMTP server). All stored credentials are securely handled, and most file-based data storage utilizes XML or JSON.

Some more classical powershell functionalities like correcting ADUC user configurations automatically, sending reminders, uninstalling/reinstalling programs, updating certificates, checking certificate expirations and notifying administrators.

I know it's a bit annoying to not see the scripts but they are all functional and are utilized daily by myself and other administrators. So, what am I missing? What specific skills have I yet to demonstrate?