r/PowerShell

A lot of Powershell instances appearing on my Task-Manager, Is this normal? Pic in Post

A lot of Powershell instances appearing on my Task-Manager, Is this normal? Pic in Post

Basically Title, Im no expert with PC's and I already ran a virus scan with malwarebytes. Nothing found. Anyone know what this is?

https://imgur.com/HArOJFq

u/ShuricanGG — 4 hours ago

How to avoid operating on the same filename repeatedly?

Hello. I have never learned PowerShell properly, and I only search on the Web to try to find a command that can do some task when needed.

Sometimes that task has been something like "rename each file in a directory".

Today I asked Edge Copilot for a one-liner to prefix each filename. It suggested:

Get-ChildItem | Rename-Item -NewName { "PREFIX_$($_.Name)" }

So I did:

Get-ChildItem | Rename-Item -NewName { "9b_$($_.Name)" }

But that resulted in some files having very long filenames 9b_9b_9b_9b_..., and then it stopped with an error about filename length.

So then Edge Copilot suggested this method, which works fine:

Get-ChildItem -File | Where-Object Name -notlike 'PREFIX_*' | Rename-Item -NewName { "PREFIX_$($_.Name)" }


But my question for you today is: When I make a command with Get-ChildItem -File, how do I tell it to do an operation just once on each file in a directory, and not treat a renamed file like a new entry to again operate on?


Some weeks ago, I had a similar symptom where I was using a one-liner of the form:

Get-ChildItem -File | Rename-Item -NewName { $_.Name -replace 'oldString', 'newString' }

and for example, if my 'oldString' was '9' and 'newString' was 9b, it would do the replacement operation repeatedly, and the resulting filename became very long: 9bbbbbbbbbbbbb...

Likewise there, I just want it to do the rename once, and not see the renamed file as a new entry to operate on again and again.

I suppose there might be some option or different order of the command so that it has the behavior I desire, instead of inserting a clause to check whether the operation has already been done.

Thanks for any help.

reddit.com
u/Righteous_Dude — 9 hours ago

PSDrive

Hi..

I have created a new PSDrive having name `S:`.

new-psdrive -name S -psprovider filesystem -root c:\users\username\dir

one running command `get-content` works fine, but `vim` is opening a blank file.

get-content S:\test.txt # works fine

vim S:\test.txt # opens a blank file

reddit.com
u/sundry_outlook — 1 hour ago

Can't figure out why complaining about catch block missing

I have this code I'm trying to generate for pulling information out of Intune. It gets most of the way thru but it's complaining with this:

>

At C:\temp\Intune\Get-UnassignediOSDEPDevices.ps1:293 char:14

>+ }

>+ ~

>The Try statement is missing its Catch or Finally block.

>At C:\temp\Intune\Get-UnassignediOSDEPDevices.ps1:294 char:8

>+ }

>+ ~

>Unexpected token '}' in expression or statement.

>At C:\temp\Intune\Get-UnassignediOSDEPDevices.ps1:295 char:3

>+ }

>+ ~

>Unexpected token '}' in expression or statement.

>+ CategoryInfo : ParserError: (:) [], ParseException

>+ FullyQualifiedErrorId : MissingCatchOrFinally

I went thru and lined up all the brackets and seems like it's correct but haven't been able to nail it down. Anyone else seeing what's going on?

<#

.SYNOPSIS

Lists all unassigned devices from Apple Device Enrollment Program (DEP) tokens in Microsoft Intune

.DESCRIPTION

This script connects to the Microsoft Graph API and retrieves all imported Apple device identities

from enrolled DEP tokens, then filters for devices that have not been assigned a user yet.

.PARAMETER ShowAllTokens

Display devices from all DEP tokens even if only one exists

.EXAMPLE

.\Get-UnassignediOSDEPDevices.ps1

Lists all unassigned iOS DEP devices across all enrollment program tokens

.EXAMPLE

.\Get-UnassignediOSDEPDevices.ps1 -ShowAllTokens

Shows devices with additional token information

#>

[CmdletBinding()]

param(

[Parameter(Mandatory = $false)]

[switch]$ShowAllTokens,

[Parameter(Mandatory = $false)]

[string]$ExportPath

)

# ============================================================================

# MODULE CHECK AND IMPORT

# ============================================================================

Write-Host "\n========================================" -ForegroundColor Cyan`

Write-Host " iOS DEP Unassigned Devices Report" -ForegroundColor Cyan

Write-Host "========================================\n" -ForegroundColor Cyan`

$RequiredModules = @("Microsoft.Graph.Authentication", "Microsoft.Graph.Intune")

foreach ($Module in $RequiredModules)

{

if (-not (Get-Module -ListAvailable -Name $Module))

{

Write-Warning "Module '$Module' not found. Installing..."

Install-Module -Name $Module -Force -Scope CurrentUser -AllowClobber -ErrorAction SilentlyContinue

}

Import-Module -Name $Module -Force -ErrorAction Stop

}

# ============================================================================

# AUTHENTICATION

# ============================================================================

Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Yellow

try

{

Connect-MgGraph -Scopes @("DeviceManagementServiceConfig.Read.All",

"DeviceManagementManagedDevices.Read.All") -NoWelcome -ErrorAction Stop

}

catch

{

Write-Error "Failed to connect to Microsoft Graph: $_"

exit 1

}

# ============================================================================

# HELPER FUNCTIONS

# ============================================================================

function Get-MgGraphAllPages

{

param(

[Parameter(Mandatory = $true)]

[string]$Uri,

[int]$DelayMs = 50

)

$AllResults = @()

$NextLink = $Uri

do

{

try

{

if ($null -ne $NextLink)

{

Start-Sleep -Milliseconds $DelayMs

}

$Response = Invoke-MgGraphRequest -Uri $NextLink -Method GET

if ($Response.value)

{

$AllResults += $Response.value

}

else

{

$AllResults += $Response

}

$NextLink = $Response.'@odata.nextLink'

}

catch

{

Write-Warning "Error fetching data from $NextLink : $_"

break

}

}

while ($null -ne $NextLink)

return $AllResults

}

function Get-UnassignedDevicesFromToken

{

param(

[Parameter(Mandatory = $true)]

[string]$TokenId,

[Parameter(Mandatory = $true)]

[string]$TokenName,

[Parameter(Mandatory = $false)]

[string]$ExpirationDate

)

try

{

Write-Host " Retrieving devices from token: $TokenName..." -ForegroundColor Gray

# Get imported Apple device identities for this DEP token

$Uri = "https://graph.microsoft.com/beta/deviceManagement/depOnboardingSettings/$($TokenId)/importedAppleDeviceIdentities"

$Devices = Get-MgGraphAllPages -Uri $Uri

Write-Host " Found $($Devices.Count) devices in this token..." -ForegroundColor Gray

# Filter for unassigned devices (no userPrincipalName assigned)

$UnassignedDevices = @()

foreach ($Device in $Devices)

{

# A device is considered unassigned if it has no userPrincipalName or addressableUserName

$IsAssigned = $false

if ([string]::IsNullOrEmpty($Device.userPrincipalName))

{

$IsAssigned = $false

}

elseif ([string]::IsNullOrEmpty($Device.addressableUserName))

{

$IsAssigned = $false

}

else

{

# Check if the user is assigned but not yet enrolled

$IsAssigned = $true

}

if (-not $IsAssigned)

{

$UnassignedDevices += [PSCustomObject]@{

TokenName = $TokenName

DeviceId = $Device.id

SerialNumber = $Device.serialNumber

Model = $Device.model

Manufacturer = $Device.manufacturer

EnrollmentState = $Device.enrollmentState

UserPrincipalName = if ([string]::IsNullOrEmpty($Device.userPrincipalName)) { "<Unassigned>" } else { $Device.userPrincipalName }

AddressableUserName = if ([string]::IsNullOrEmpty($Device.addressableUserName)) { "<Not Set>" } else { $Device.addressableUserName }

CreatedDateTime = $Device.createdDateTime

LastContactedDate = $Device.lastContactedDateTime

}

}

}

return $UnassignedDevices

}

catch

{

Write-Warning "Error retrieving devices from token '$TokenName': $_"

return @()

}

}

# ============================================================================

# MAIN SCRIPT LOGIC

# ============================================================================

try

{

# Step 1: Get all DEP tokens (Enrollment Program Tokens)

Write-Host "\n[Step 1] Retrieving Enrollment Program Tokens..." -ForegroundColor Yellow`

$DepTokensUri = "https://graph.microsoft.com/beta/deviceManagement/depOnboardingSettings"

$AllTokens = Get-MgGraphAllPages -Uri $DepTokensUri

if ($AllTokens.Count -eq 0)

{

Write-Host "\n[!] No Enrollment Program Tokens found in this tenant." -ForegroundColor Red`

exit 1

}

Write-Host " Found $($AllTokens.Count) DEP token(s)" -ForegroundColor Green

# Step 2: Get all enrolled iOS devices from Intune for comparison

Write-Host "\n[Step 2] Retrieving managed iOS devices..." -ForegroundColor Yellow`

$ManagedDevicesUri = "https://graph.microsoft.com/beta/deviceManagement/managedDevices?\$filter=operatingSystem eq 'iOS'"`

$EnrolledDevices = Get-MgGraphAllPages -Uri $ManagedDevicesUri

Write-Host " Found $($EnrolledDevices.Count) managed iOS devices" -ForegroundColor Green

# Step 3: Build comparison dictionary for already enrolled devices

$EnrolledSerialNumbers = @{}

foreach ($Device in $EnrolledDevices)

{

if ([string]::IsNullOrEmpty($Device.serialNumber))

{

continue

}

$EnrolledSerialNumbers[$Device.serialNumber] = $true

}

# Step 4: Get unassigned devices from each token

Write-Host "\n[Step 3] Finding unassigned devices..." -ForegroundColor Yellow`

$AllUnassignedDevices = @()

foreach ($Token in $AllTokens)

{

`$DeviceList = Get-UnassignedDevicesFromToken ``

`-TokenId $Token.id ``

`-TokenName $Token.tokenName ``

-ExpirationDate $Token.tokenExpirationDateTime

# Filter out devices that are already enrolled (in managedDevices)

$FilteredDevices = @()

foreach ($Device in $DeviceList)

{

if (-not $EnrolledSerialNumbers.ContainsKey($Device.SerialNumber))

{

$FilteredDevices += $Device

}

}

$AllUnassignedDevices += $FilteredDevices

Write-Host " Token '$($Token.tokenName)': $($DeviceList.Count) unassigned devices" -ForegroundColor Gray

}

# Step 5: Display results summary

Write-Host "\n[Step 4] Results Summary..." -ForegroundColor Yellow`

if ($AllUnassignedDevices.Count -eq 0)

{

Write-Host "\n[✓] All DEP devices have been assigned a user!" -ForegroundColor Green`

}

else

{

# Group by token for summary display

$TokenSummary = $AllUnassignedDevices | Group-Object TokenName

Write-Host "Total unassigned devices: $($AllUnassignedDevices.Count)" -ForegroundColor Red

Write-Host "\nBreakdown by Enrollment Program Token:" -ForegroundColor Yellow`

foreach ($Group in $TokenSummary)

{

Write-Host " - $($Group.Name): $($Group.Count) unassigned devices" -ForegroundColor Cyan

}

# Display detailed list of unassigned devices

Write-Host "\n========================================`n" -ForegroundColor Cyan`

`$AllUnassignedDevices | Sort-Object TokenName, SerialNumber | Format-Table ``

`-AutoSize ``

-Property @(

@{Label="Token";Expression={$_.TokenName}},

@{Label="Serial Number";Expression={$_.SerialNumber}},

@{Label="Model";Expression={$_.Model}},

@{Label="Manufacturer";Expression={$_.Manufacturer}},

@{Label="Enrollment State";Expression={$_.EnrollmentState}},

@{Label="User Assigned";Expression={$_.UserPrincipalName}}

)

Write-Host "\n========================================`n" -ForegroundColor Cyan`

# Export to CSV if path specified

if ($ExportPath)

{

try

{

$AllUnassignedDevices | Export-Csv -Path $ExportPath -NoTypeInformation -Encoding UTF8

Write-Host "[✓] Results exported to: $ExportPath" -ForegroundColor Green

}

catch

{

Write-Warning "Failed to export to CSV: $_"

}

}

}

}

catch

{

Write-Error "\nScript failed: $($_.Exception.Message)"`

exit 1

}

finally

{

# Disconnect from Microsoft Graph

try

{

### Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null

Write-Host "\nDisconnected from Microsoft Graph" -ForegroundColor Gray`

}

catch

{

}

}

Write-Host "\nScript completed successfully!" -ForegroundColor Green`

Note so in theory it's upset about one of the squiggly brackets between

Write-Warning "Failed to export to CSV: $_"

statement and the Catch statement.

Just everything seems matched up right.

reddit.com
u/jriker2 — 17 hours ago

Weird Behavior: Can't get files from OneDrive in PowerShell

I'm attempting to clean up a OneDrive folder that a user accidentally created a whole bunch of duplicated files.

One odd thing I'm running into is when I get the filename of two files I want to compare to see if I can remove them (using commands like Get-Item, Get-FileHash, Copy-Item, and Remove-Item) is when I get the full path of the object it acts as if that path doesn't exist - even though I got the path from the output of "Get-ChildItem $SourceDir -File -Recurse"

When I looked in the directory in question I also see that they're all listed as links (mode is -a---l) which I suspect is an issue. I've forced OneDrive to download the files to disk, but still no change in behavior.

If anyone else has suggestions or guidance, I appreciate it!

reddit.com
u/TheBigBeardedGeek — 19 hours ago
🔥 Hot ▲ 55 r/PowerShell

M365-Assess v2.0 - we just shipped a major rewrite of the report and expanded to 274 checks

Posted about v1 here a while back. v2.0 is a substantial update, so figured it was worth a follow-up.

The big change: the report engine.

The original report was generated by a single 4,424-line PowerShell function. The entire HTML document was assembled through string concatenation — table rows, chart data, CSS, JavaScript, all of it built in PowerShell. Making a UI change meant editing string templates. The output file exceeded 6MB.

V2.0 replaces it with a three-stage pipeline:

# Stage 1: assessment runs, writes CSV exports
Invoke-M365Assessment

# Stage 2: Build-ReportData.ps1 converts CSVs to a structured JSON blob
# Stage 3: compiled React app + JSON are inlined into a single HTML file

The assessment logic and the report UI are now completely separate. The React app is compiled independently and inlined at build time — the output is still a single portable HTML file, but each layer is independently maintainable and testable. Report size: 6MB+ → 1.3MB.

Auth consolidation.

V1 had ad-hoc authentication handling. V2.0 enforces parameter sets — certificate, device code, managed identity, app secret, and pre-existing connection each have a distinct set. You get proper tab completion, no invalid combinations, and full CI/CD pipeline support for automated assessments without interactive sign-in.

Compare-M365Baseline

New cmdlet that takes two scan output folders and generates a drift report — what improved, what regressed, what shifted. The output is the same HTML report format.

License-aware checks.

The module now reads your tenant's service plan assignments at the start of each run and skips checks for features you haven't licensed. Avoids false positives from Defender plans you don't have, Purview features not in your SKU, etc.

Coverage:

274 checks across Identity (Entra ID), Exchange Online, Intune, Security (Defender / Secure Score), Collaboration (Teams / SharePoint / OneDrive), PowerBI, Hybrid AD, and Purview. Mapped to 14 compliance frameworks.

Available on PSGallery:

Install-Module M365-Assess
Invoke-M365Assessment

MIT licensed. Read-only Graph API. No telemetry.

GitHub: https://github.com/Galvnyz/M365-Assess Full writeup: https://galvnyz.com/blog/m365-assess-v2

Happy to answer questions.

Posted about v1 here a while back. v2.0 is a substantial update, so figured it was worth a follow-up.

The big change: the report engine.

The original report was generated by a single 4,424-line PowerShell function. The entire HTML document was assembled through string concatenation — table rows, chart data, CSS, JavaScript, all of it built in PowerShell. Making a UI change meant editing string templates. The output file exceeded 6MB.

V2.0 replaces it with a three-stage pipeline:

# Stage 1: assessment runs, writes CSV exports (Invoke-M365Assessment)
# Stage 2: Build-ReportData.ps1 converts CSVs to a structured JSON blob
# Stage 3: compiled React app + JSON are inlined into a single HTML file

The assessment logic and the report UI are now completely separate. The React app is compiled independently and inlined at build time, the output is still a single portable HTML file, but each layer is independently maintainable and testable. Report size: 6MB+ → 1.3MB, and we ship three color themes included.

Auth consolidation.

V1 had ad-hoc authentication handling. V2.0 enforces parameter sets — certificate, device code, managed identity, app secret, and pre-existing connection each have a distinct set. You get proper tab completion, no invalid combinations, and full CI/CD pipeline support for automated assessments without interactive sign-in.

Compare-M365Baseline

New cmdlet that takes two scan output folders and generates a drift report — what improved, what regressed, what shifted. The output is the same HTML report format.

License-aware checks.

The module now reads your tenant's service plan assignments at the start of each run and skips checks for features you haven't licensed. Avoids false positives from Defender plans you don't have, Purview features not in your SKU, etc.

Coverage:

274 checks across Identity (Entra ID), Exchange Online, Intune, Security (Defender / Secure Score), Collaboration (Teams / SharePoint / OneDrive), PowerBI, Hybrid AD, and Purview. Mapped to 14 compliance frameworks.

Available on PSGallery:

Install-Module M365-Assess
Invoke-M365Assessment

MIT licensed. Read-only Graph API. No telemetry.

GitHub: https://github.com/Galvnyz/M365-Assess
Full writeup: https://galvnyz.com/blog/m365-assess-v2

Happy to answer questions.

u/WhatThePuck9 — 1 day ago

Built an Interactive PowerShell session in the browser, looking for testers.

Hi all,

I’m a .NET developer and a regular PowerShell user. I’ve been building a project that brings a secure, fully interactive PowerShell session into the browser, with on-demand access for end users or servers, especially in this era of modern, internet-first managed devices.

I’m looking for a few genuine testers to try it out and give honest feedback, mainly to see whether there’s any real appetite for something like this and whether it’s worth continuing to develop.

If you’re interested, feel free to DM me.

You can read more here: https://shellaccess.io
(Not a promotion, I’m not accepting customers or payments at this time)

u/LGeevo — 1 day ago

Powerplan And Brightness Selector. A power plan switcher script to automate applying Windows power plans and brightness for laptops depending on running applications.

There are quite a few power plan switchers out there. Some are free but lack some features I needed, while the paid ones still don't offer everything I was looking for.

Therefore, I’ve spent an afternoon creating a small utility that does what I want. I call it PABS (Powerplan And Brightness Selector). It’s a single script that runs in the tray and manages everything based on your active apps and power source using minimal CPU resources.

Key features:

  1. No bloat – pure PowerShell, minimal resources.
  2. Free – open source for everyone.
  3. It actually cares about brightness – unlike most switchers.
  4. Executable-Path-Based Priorities: Higher items in your watchlist have higher priority. If you have a game and a browser open, the game's plan wins.
  5. AC/DC Awareness: Separate automation rules for when you're plugged in vs. on battery.
  6. Brightness Inheritance: If you manually adjust your brightness, PABS "remembers" it and carries it over to the next plan (no more 100% brightness flashes!).
  7. Manual Brightness Sync (Ctrl+Shift+B): Instantly push your current brightness level to ALL plans.
  8. Stealth Dashboard: Runs hidden in the tray. You can toggle a Dashboard log window to see what's happening.
  9. Bulletproof: The console "X" button is disabled to prevent accidental closure (exit via tray only).
  10. Tailored to you: Easy to modify the code to fit your specific needs.

To make the script work, you may need to do a few things first:

  1. (Optional) Take a look at power plans table:

# list of defined power plans mapped to their system GUIDs

$PowerPlans = @{

"Ultra" = "e9a42b02-d5df-448d-aa00-03f14749eb61"

"High" = "8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c"

"Balanced" = "381b4222-f694-41f0-9685-ff5bb260df2e"

"PwrSaver" = "a1841308-3541-4fab-bc81-f71556f20b4a"

}

It contains standard Windows power plan GUIDs. The names in the table have of course nothing to do with Windows PP names and are used as labels within the script. I like to use names like this:

$PowerPlans = @{ "ExtremeUltraHiperMegaTurboBlastingPowerUltimateNitroWarp" = "guid-here"

...

}

You can add of course your custom power plans GUIDs. To display the list of PP open cmd.exe or powershell and type:

powercfg /l

2. (Mandatory) Configure the switching logic by editing the $WatchList* tables:

This is the AC watchlist:

$WatchListAC = @(

@{ Path = "C:\Games\*"; Plan = "Ultra" } # Top Priority

@{ Path = "C:\Apps\Editor\*"; Plan = "High" } # Lower Priority

)

In the above example, there are two monitored directories. Any application from C:\Games and its subdirectories will trigger the "Ultra" plan.

If you start any app from the C:\Apps\Editor directory while a game is already running, the "Ultra" plan will remain active (due to higher priority) until you close the game. Only then will it switch to "High".

If all watched apps are closed, the script reverts to your default ($DefaultPPAC = "Balanced").

The script is designed to automatically find your Brightness GUID by searching for the "Display brightness" string in your power settings, but you may want to verify it manually.

To do this run:

powercfg /q SCHEME_CURRENT SUB_VIDEO

Look for the section named "Display brightness"—the GUID listed there is what the script uses to control your screen. If the brightness control is not working, that's the place to dig.

How to run PABS after you configure watchlists:

Code:

https://pastebin.com/5fTWHSXj

I tested it on Windows 10 but it should work on 11 as well.

It's not much, but it’s a tiny, "set and forget" tool that made my laptop experience much smoother. As I said - the code is free, but I'll be happy if you keep the credits intact! ;)

reddit.com
u/Glad-Journalist-4807 — 3 days ago

Struggling with renaming (ren)

CLI noob here. Let me know if there's a better sub for this.

I have the following files...

File_January_2020.pdf

File_January_2021.pdf

File_February_2020.pdf

File_February_2021.pdf

I want to end up with

File_2020-01.pdf

File_2021-01.pdf

File_2020-02.pdf

File_2021-02.pdf

But I keep jacking it up. For example, attempts have resulted in "File_-04il_2020.pdf" and "File_April_2020.pdf-04" when trying to rename the April files.

I'd like to do this in one batch file.

Again, apologies if I'm in the wrong place for this question

reddit.com
u/Elpidiosus — 3 days ago
🔥 Hot ▲ 156 r/PowerShell

PsUi: PowerShell UIs made slightly less shitty

I've worked on this over the past year and change. It's probably most useful for internal tools (tools for your helpdesk or whatever). It abstracts the horror of WPF over PowerShell into a slightly more palatable experience.

It'll allow you to avoid XAML. You won't have to worry about runspaces or Dispatcher.Invoke. You call functions, things show up on screen, the window doesn't freeze when your script runs. All the threading shit is buried in a C# backend so you can worry about the actual PowerShell logic.

If you've ever tried to implement WPF for PowerShell properly (runspace pools, synchronized hashtables, dispatchers) you know that setup is a massive pain in the balls from the start. One wrong move and your UI thread has shit the bed, your variables are gone, and your beautiful form has collapsed in on itself with the weight of a neutron star. I went through all of that so you don't have to. My sanity went to hell somewhere around month four but hey, the module (probably) works.

So how it actually works: your -Action scriptblocks don't run on the UI thread. They run on a pre-warmed RunspacePool in the background (pool of 1-8 runspaces, recycled between clicks so there's no spinup cost). When you define a control with -Variable 'server', the engine hydrates that value into the runspace as $server before your script runs, and dehydrates it back to the control when it's done. It's by-value, not by-reference, so form data (strings, booleans, selected items) round-trips cleanly. If you need to pass heavier objects between button clicks there's a $session.Variables store for that.

The host interception is there because running scripts off the UI thread breaks every interactive cmdlet. Write-Host doesn't have a console to write to. Read-Host has nobody to ask. Write-Progress has nowhere to render. Get-Credential just dies. So PsUi injects a custom PSHost that intercepts all of that and routes it back to the UI. Write-Host goes to a console panel with proper ConsoleColor support, Write-Progress drives a real progress bar, Read-Host pops an input dialog on the UI thread and blocks the background thread until you answer, Get-Credential does the same with a credential prompt, and PromptForChoice maps to a button dialog. The output batches in chunks so if your script pukes out 50k lines the dispatcher queue doesn't grow unbounded and murder the UI.

Controls talk to the background thread through a proxy layer that auto-marshals property access through the dispatcher. You don't see any of this, you just write $server and it works.

New-UiWindow -Title 'Server Tool' -Content {
    New-UiInput -Label 'Server' -Variable 'server'
    New-UiDropdown -Label 'Action' -Variable 'action' -Items @('Health Check','Restart','Deploy')
    New-UiToggle -Label 'Verbose' -Variable 'verbose'
    New-UiButton -Text 'Run' -Accent -Action {
        Write-Host "Hitting $server..."
        # runs async, window stays responsive
    }
}

Controls include inputs, dropdowns, sliders, date/time pickers, toggles, radio groups, credential fields, charts, tabs, expanders, images, links, web views, progress bars, hotkeys, trees, lists, data grids, file/folder pickers, and a bunch of dialogs. Light theme by default, dark if you pass -Theme Dark.

PSGallery:

Install-Module PsUi

https://github.com/jlabon2/PsUi

GIF of it in action: https://raw.githubusercontent.com/jlabon2/PsUi/main/docs/images/feature-showcase.gif

Works on 5.1 and 7. If you do try it and anything breaks, please open an issue and let me know.

u/Jagula — 4 days ago

How does assoc/ftype work with $args?

Hello.

I have a script that relies on args to pull in a file to edit:

$path = args[0]
$file_stream = [System.IO.File]::OpenRead($path)
# etc

I compiled this script into an .exe, and would like this to be associated with the filetype so that I can simply open it up in the Powershell script .exe that does the task.

I used assoc and ftype to associate the file extension with the created .exe. However, it seems to not work with "Open with..." and/or opening the file with Explorer. The script does work as intended in the case that I launch it within a Powershell instance or simply drag the file into the exe.

So my question is, if the $args are still working when dragging, what is going on under the hood with assoc/ftype and "Open with..." that I need to adjust within the script before compiling again?

reddit.com
u/v32modem — 3 days ago

Using PowerShell to generate structured repo context for LLM workflows, does this approach make sense?

I kept running into the same issue with coding LLMs: when repo context is incomplete, they start making incorrect assumptions about files, structure, and function behavior.

I’ve been experimenting with a PowerShell-based approach that:

  • scans a repository
  • builds the directory tree
  • extracts relevant signatures/contracts
  • generates structured context artifacts for LLM workflows

The reason I chose PowerShell was mainly Windows-native execution, easy scripting integration, and avoiding unnecessary tooling overhead for local repo inspection.

I’m curious what PowerShell users think about this direction.

Does PowerShell feel like a reasonable fit for this kind of repository/context orchestration workflow, or would you consider it the wrong tool for the job?

reddit.com
u/PalpitationWaste7681 — 2 days ago

Breaking huge PWSH module up to smaller parts

Hey guys, I have a personal module I've written for wrapper functions, aliases, and other tools to help me with my everyday work and pwsh use.

The module has become too big for my taste, around 2800 lines. This makes editing and searching for functions a bit tedious.

So, I've decided to try and break the module off into smaller components, each containing a handful of functions, currently being separated by regions in the module ps1m file.

I'm trying to get it to work with Invoke-Expression but it appears that the functions do not get loaded properly.

Here's how I'm trying:

$moduleFolder   = (Get-Module -ListAvailable MODULENAME).ModuleBase
$functionFiles  = gci $moduleFolder -Recurse | ?{$_.Extension -eq ".ps1"}


foreach ($func in $functionFiles)
{
    iex $func.FullName
}

SampleFunction

SampleFunction throws the standard "not recognised as a name of a..." error message.

What do you think I'm doing wrong?

reddit.com
u/MFZozzy — 4 days ago

Open-source tool that visualizes your Azure Automation Account as an interactive mind map

If you manage Azure Automation Accounts you've probably had to answer questions like "which runbooks use this credential?" or "what breaks if I delete this variable?" and had to click through dozens of portal pages to find out.

I built Azure Automation MindMap to solve that. It connects to your Azure tenant using your own Microsoft account (MSAL, delegated auth, read-only) and renders the entire account as a live interactive graph.

What it shows:

  • All runbooks with their asset dependencies (variables, credentials, connections, certs, schedules)
  • Key Vault secret references per runbook
  • Job history (7/30 day trends, colour-coded Failed / Completed w/ Errors / OK)
  • Schedule health (healthy / warning / expired / disabled)
  • Hybrid Worker Groups with worker online/offline status
  • Managed Identity status
  • Built-in security scanner (static analysis on each runbook's PS source):
  • Hardcoded passwords ($password = "...", ConvertTo-SecureString "..." -AsPlainText)
  • Variable indirection (e.g. $x = "secret" → ConvertTo-SecureString $x -AsPlainText)
  • Deprecated RunAs account patterns
  • Three views: Runbooks (dependency graph), Objects (asset-centric / impact analysis), Table (bulk review).

Full setup from zero to running locally takes under 10 minutes — the repo includes a SetupLocal.ps1 script that handles everything.

Article with step-by-step setup: https://www.powershellcenter.com/2026/04/18/automation-account-mindmap/

GitHub: https://github.com/farismalaeb/AutomationMindMap

Feedback and PRs welcome — happy to answer any questions.

u/farismalaeb — 3 days ago

Just released Servy 7.9 - Now with a much faster and secure PowerShell module

Hi everyone,

It's been about two months of coding and too many cups of coffee since my last post about Servy here. I've shipped several updates since then, but this one is a real milestone. The community response has been amazing: ~1,600 stars on GitHub and ~34,000 downloads.

If you haven't seen Servy before, it's a Windows tool that runs any app as a native Windows service with full control over its configuration, parameters, and monitoring. It provides a desktop app, a CLI, and a PowerShell module that let you create, configure, and manage Windows services interactively or through scripts and CI/CD pipelines. It also comes with a Manager app for easily monitoring and managing all installed services in real time.

In this release (7.9), I've added/improved:

  • Improved PowerShell Module Performance: Replaced all WMI with native P/Invoke, making commands significantly faster and more reliable.
  • Improved security: Automatic Directory Hardening (ACLs) and Machine-Unique Encryption (Dynamic Entropy)
  • Custom Logging: Added LogRotationSizeMB, LogRollingInterval, LogLevel, and EnableEventLog configs for better observability in production environments.
  • General Polish: Fixed many issues across the PowerShell module, CLI, and core components.

Check it out on GitHub: https://github.com/aelassas/servy

Demo Video: https://www.youtube.com/watch?v=biHq17j4RbI

Any feedback or suggestions are welcome.

reddit.com
u/AdUnhappy5308 — 5 days ago

Might be missing something with IWR

I'm doing an iwr and I'm getting back things like any idea what i'm missing?

QQ�!�H�@#e���E`���:���o��n~�j�+�Ma!���5I��OO���Y��v
�J#��LM����)��-�P�r�o��;S*

]R�µ^"���ۏХ��2����D��Hlj�~��i3�Gr��q��4��T3HߕN{I�ò�P��<co-���vR�$�O,�#œ5�&�^?o�w��+�1�v�܎�{Ø��:�J]��$ގ_]^]�[z^<����<.=ߎi_�y�bz���|������o���az�����4rq�30�%�ḧ́9�u��fR��'	�9�!�c d~7�{tCZg� I�g ��˚6G�"����L����YO��I=]��Ѱ9:���`e����Q��[��9.᧵K~�K�\��<C��S�pp�緡�e��H�/}LK�:��^f�),n�-��=��ZB�Inr���#`C��6kԥ�5���a�.M��4�Sh4XJ'?�k�O���9BҘ$M�̴3��6r�"���#�ןOQ#O�j�O#7������w���t~�cN5�o{Ǫ��f���i�d�S����r�8�K��\o���HWR l��g'�wc�:v	��M���^�7��@e�t��/��hb�a��������K���[�����9�n�I��k�4�J&>$$#�8��h4i�wn�
� 5�c;?�Y����I:=��)d�0�ٛ���K��I���t�p��<}>I=6j�*�F�8.�x#�8K����M8�׉\.r��$V��*����Я?�gY<��5�jx46s���A��O��W����N��啺@oIN�h����0X��יH�n	I�Y��N��x
F�����F�$�u��;>��^���tXS��n 
v��%��	.�̸6�{/iB��g��:�ץܤ�>:�-���7WN���n��!i��uL�-
reddit.com
u/rogueit — 4 days ago

System.Array IF/ELSE Statement Problem

I'm struggling with writing an IF/ELSE statement for a System.Array. The array is populated with the following, returning a value of True if a folder contains a document:

>-TEST CONTAINER

>|-- FOLDER = Documents | HAS_DOCUMENTS = (True)

>|-- FOLDER = Misc | HAS_DOCUMENTS = (False)

I need to correctly identify if a folder has any documents and if not, send a delete request.

However, trying different IF/ELSE statements gleaned from forums and articles, at the end of the Main function, when removing and adding a document to/from a folder, the results don't match reality.

In the getFolder function, I've tried to simplify things by not retrieving all folders ($folder.type -eq "folder") and instead retrieving folders with a has_document property value of true ($folder.has_documents -eq "True").

However, I'm struggling with getting a working IF/ELSE statement and would be really grateful for guidance on where I'm going wrong. I suspect the issue lies in the IF statement, because it seems to fall back to the ELSE statement.

function getFolder
{
    param($folderList, $prefix)
    if ($folderList.Count -eq 0)
    {
        return
    }
    else
    {
        foreach($folder in $folderList)
        {
            if ($folder.type -eq "folder")
            {
                Write-Host "$($prefix) FOLDER = $($folder.name) | HAS_DOCUMENT = ($($folder.has_documents))"
                if ($folder.has_subfolders)
                {
                    $resource = https://$server/api/customers/$customerId/stores/$store/folders/$($folder.id)/children?limit=9999
                    $response = Invoke-RestMethod -Method Get -Uri "$resource" -Header $header
                    $newprefix = "$($prefix)--"
                    getFolder $response.data $newprefix
                }
            }
        }
    }
}

function Main {
$csv = Import-Csv -Path "C:\API\Container-Get\Container-Get.csv"

$csv | ForEach-Object { 
    # CSV variables
    $containerId = $_.CONTAINERID
    $store = $containerId.Substring(0, $containerId.IndexOf('!'))

            $resource = https://$server/api/customers/$customerId/stores/$store/containers/$containerId
            $response = Invoke-RestMethod -Method Get -Uri "$resource" -Header $header

            $response.data.name

            $resource = $resource + "/children"
            $response = Invoke-RestMethod -Method Get -Uri "$resource" -Header $header
            [System.Array] $folders = $response.data

            # Print retrieved container and folders.
            Write-Host "The names of folders within container $containerName :`n"
            Write-Host "-$containerName"
            getFolder $folders "|--"

            #########################################################
            if ($folders -contains "True") {'Container is not empty'}
            else  {'Container can be deleted'}

            if ($folders -ne $NULL) {'Container is not empty'}
            else  {'Container can be deleted'}

            $folders.Contains('(True)') #Returns false 
}
reddit.com
u/viewtifulstranger — 5 days ago

PoSHBlox 0.6.0 - What's new since last time!

PoSHBlox 0.6.0

I have returned since my initial announcement and thank you for all of the feedback on PoSHBlox!

Visual node-graph editor for building PowerShell scripts. Drag, connect, run. Main changes since 0.3.0:

  • Node model rewrite. 0.3.0 had one input pin and one output pin per node. 0.6.0 has a dedicated execution pin for control flow and a data pin for every parameter. You can wire $ComputerName from one node directly into -ComputerName on another without using the pipeline.
  • Undo / Redo everywhere - adds, deletes, drags, reparenting, param edits, container resizing, parameter-set switch.
  • Multi-select - click drag lasso, shift-click, group drag, group delete.
  • Clipboard - Ctrl+C / X / V for copy, cut, and paste
  • Splice - right-click a wire, insert a node inline.
  • Module import overhaul - pick from a list populated by Get-Module -ListAvailable, version exclusive edition badges (PS7 / PS 5.1), progress overlay for big modules.
  • Dual-host introspection - scans both PowerShell 7 and PowerShell 5.1 when available. Parameters carry per-edition availability; the UI warns when the active host doesn't support a param you've wired.
  • Robust introspector - auto-loads on demand, falls back through wildcards / .psd1 / per-command enumeration, tolerates snap-ins and compiled-module quirks on 5.1.
  • Validation - nodes with missing mandatory params or wrong parameter set get a red border and badge; properties panel lists the error reasons.
  • Splatting - cmdlets with 4+ wired args emit as $p = @{...}; Cmd @p instead of one long line.
  • Progressive help text - per-parameter descriptions expand inline on click.
  • [switch] split from [bool] - switches now emit bare -Name, not -Name $true.
  • Codegen - String/Path/Enum textbox values emit double-quoted with $var / $(...) expansion; Credential / HashTable pass-through as raw expressions.

Some features on the roadmap:
- Script --> PoSHBlox nodes
- Multi-output variable names
- In-app execution overlay instead of spawning new powershell window to test
- winget / choco submissions for wider availability

Let me know what you guys think, definitely an exciting project for me and I hope you get some mileage and fun out of it! Enjoy :)

Repo: github.com/obselate/PoSHBlox
Release: v0.6.0

u/xazzzzzzz — 3 days ago