r/PowerShell

I wanted to run scripts in the logged-on user’s security context, so I built a PowerShell module

I wanted to run scripts in the logged-on user’s security context, so I built a PowerShell module

I kept running into situations where a fix needed to happen in a logged-on user session (HKCU, Explorer, user-installed apps, notifications, browser settings, Outlook auth, etc.), but most automation tools execute as NT AUTHORITY\SYSTEM or require the user’s password.

Existing approaches definitely exist, and some are quite clever, but I kept running into tradeoffs that didn’t fit what I wanted:

  • Asking for the user’s password
  • Interrupting the user session
  • Scheduled task workarounds
  • Poor targeting in terminal server / multi-session environments
  • Remoting-style object serialization limitations when passing data back and forth

So I built PSUserContext: a binary PowerShell module for running scripts in another user's interactive session and security context.

Some scenarios where this has been useful:

  • Restarting user processes (explorer.exe, Teams, browsers)
  • User profile remediation
  • Outlook profile/config fixes
  • User-scoped app troubleshooting

A few design goals:

  • Execute from SYSTEM / RMM contexts
  • Run inside an existing logged-on user session
  • No user password required
  • No session takeover or interruption
  • Better object handling than traditional remoting serialization

GitHub:
https://github.com/walliba/PSUserContext

Still actively evolving, so I’d appreciate feedback, criticism, weird edge cases, or “why didn’t you just do X?” from people who’ve solved similar problems.

u/leuit — 8 hours ago

BatEx: an open source tool to turn .bat/.cmd/.ps1 scripts into EXE apps

Hey everyone,

I made BatEx, an open source Windows app that converts .bat, .cmd, and .ps1 scripts into .exe applications.

It is built with C#, .NET 8, and WinUI 3.

Features:

  • Show or hide the console window
  • Run the generated EXE as administrator
  • Add a custom `.ico` icon
  • Add file metadata
  • Choose x64, x86, or AnyCPU
  • Optional script obfuscation
  • Build log and conversion history

The Program now supports ps1 files!

I'd appreciate your feedback, bug reports, or suggestions.

GitHub:

https://github.com/TheYali1/BatEx

Download:

https://github.com/TheYali1/BatEx/releases

reddit.com
u/TheEZ45 — 20 hours ago

Login notification script?

Hey guys. What's a good script I can use with a Telegram bot to send notifications to my phone whenever someone tries to unlock/log into my PC? I've never used PowerShell before and don't know if I can trust the script that Google and OperaAI gave me. I really want to have this bit of security for my PC for peace of mind whenever I'm not at home for multiple days

reddit.com
u/CryptoMain03 — 18 hours ago

It seems that PowerShell 7 will ship with Windows Server vNext

In this video they talk about what the plans are for Windows Server vNext (basically Windows Server 2028 or whatever it ends up being called): https://youtu.be/tElXJ63_z7w?t=2300
Here they say that they are working towards making PS7 the default in the next version of Windows Server and that 5.1 (mistakenly called 5.2) will likely be an optional component.

This is great news because forever being stuck on the old unmaintained .NET Framework and Windows PowerShell 5.1 made PowerShell less attractive to developers who want to use new .NET features.

I wonder if the sudden requirement for the MSIX deployment is related to this. Perhaps there's plans on making MSIX work on Server Core? I don't know, but this makes me more hopeful for the future of PowerShell than the MSIX announcement did.

u/Thotaz — 1 day ago

Fish-Like Syntax Highlighting

The Fish shell for Linux (as well as the zsh-syntax-highlighting package for zsh) has a command syntax highlighting feature that is quite helpful. PowerShell has this somewhat with the PSReadLine feature, but it's missing a critical part that I miss from Fish. In Fish, when you would type a command that was incorrect, as you were typing it would highlight the command as one color if it was invalid, and another if it was valid (valid meaning builtin or in path). Is there any way to get this functionality in PowerShell (7.0+)?

reddit.com
u/themor69 — 1 day ago

Does anyone have an easy guide for signing scripts?

I really need to sign my scripts, but unfortunately my brain tends to shut down when it comes to cert things aside from just "load file." Appreciate it!

reddit.com
u/TheBigBeardedGeek — 1 day ago

Static Sites are Simple (with PowerShell)

I've been doing WebDev since the dawn of the internet, and I've been doing PowerShell for almost 20 years now. I want to share with you something that I've realized over the years:

Static Sites Are Simple

Static Websites are just a bunch of files. You can make static sites with anything that can make files.

Static Sites are Simple.

Let me show you how:

Static Sites with PowerShell

PowerShell is pretty great at making files.

Most static site files are text: .css, .js.,.html,.svg are all readable and writeable text.

Want to write a website in PowerShell?

Just write a series of strings.

I like this naming convention:

# *.html.ps1 > *.html

We can build a site like this:

# Get all *.html.ps1 files beneath the current directory
Get-ChildItem -Filter *.html.ps1 -Recurse -File | 
   Foreach-Object {
      # Run the file 
      & $_ > $(
          # and redirect the output to the renamed `.html`
          $_.Fullname -replace '\.html\.ps1$','.html'
      )
   }

If we wanted to provide consistent formatting for all *.html.ps1 files, we can do so with a layout.

Just write a freeform script for layout.

function layout {
   
   # Output any common layout.

   # We are outputting a series of strings.

   # When we redirect output, each string will go on it's own line.
   
   # We can use any simple PowerShell string techniques to change content
   
   '<html>' # * Single quoted string (no substitutions)
   "<head>" # * Double quoted string (`$var` and `$(expression)` supported) 
       # * Multiline double quoted strings (with subexpressions)
       "<title>$(
        if ($title) { 
            [Web.HttpUtility]::HTMLEncode($title)
        } else { 'My Website' }
        )
        </title>"
        # * Conditionals output, using if
        if ($Header) {
             "$Header" # * Stringification of variables
        }
        # * Singly quoted here-strings (mulit-line no substitution)
        @'
<style>
body {max-width: 100vw;height: 100vh;}
</style>
'@
        # * Doubly-quoted here-strings 
        @"
$(
# * Subexpressions with conditionals and iteration
if ($css) {$css})
"@

   "</head>"
   "<body>"
    # * `$input` allows us fast, one-time enumeration of a pipeline
    # * `@()` allows us to collect that into a new list
    $allInput = @($input)
    
    # * String operators (`-join`, `-like`, `-match`,`-replace`, `-split`).
    $allInput -join [Environment]::Newline
    "</body></html>"
}

Now, we can build it with:

# Get all *.html.ps1 files beneath the current directory
Get-ChildItem -Filter *.html.ps1 -Recurse -File | 
   Foreach-Object {
      # Run the file, pipe to our layout 
      & $_ | layout > $(
          # and redirect the output to the renamed `.html`
          $_.Fullname -replace '\.html\.ps1$','.html'
      )
   }

If we want to handle multiple file types, a switch statement does a nice job. We can build the site any way we want. This is just one example of how.

Most templating languages can't talk to too much. By using PowerShell to make static sites, we open up a wide world of possibilities with a small amount of understanding.

Static Sites Are Simple

They're mainly just strings.

PowerShell plays with strings quite well 😉.

Hope this Helps / AMA

reddit.com
u/StartAutomating — 2 days ago

What's your go-to trick for speeding up PowerShell loops on large datasets

Been processing some pretty chunky datasets lately and kept running into the usual pain points. The biggest wins I've found are swapping out repeated Where-Object scans inside loops for hashtable lookups, and, being strict about filtering and selecting only what I need before anything enters the loop at all. Also switched from building arrays with += to using Generic.List[T] from the start, which made a, noticeable difference over ArrayList and is generally the better call now if you want typed, efficient accumulation. Still occasionally go back and forth on foreach vs ForEach-Object, but honestly less so these days. For stuff already in memory, foreach wins pretty consistently because ForEach-Object carries pipeline overhead that adds up fast on large collections. I keep ForEach-Object for when I'm actually streaming from a file or pipeline and don't want everything loaded into memory at once. Haven't gone deep on ForEach-Object -Parallel yet, worth noting that's PowerShell 7+ only if you're still on 5.1. The overhead hasn't been worth it for most of what I do, but curious if others have found a sweet spot for when it actually pays off. My gut says it only really shines when tasks are genuinely independent and the per-item work is heavy enough to justify the thread spin-up cost. One thing I've started doing more is running Measure-Command before assuming the loop itself is the bottleneck. Turns out a lot of the time the real culprit is I/O, remoting latency, or logging, not the iteration logic at all. What's the change that made the biggest difference for you?

reddit.com
u/inperbio — 3 days ago

I don't get Powershell 7.6.1 via Microsoft Update

As the title says. Several computers with Windows 11 with the same problem. I activated both options in the Powershell 7.6 installers ("Enable updating Powershell through Microsft Update", and "Use Microsoft Update when I check for updates"). Updated to Powershell 7.6 from Powershell 7.5.4 by installing the .msi.

Any ideas why it doesn't come via Microsoft Update?

reddit.com
u/chk17 — 4 days ago

Words of wisdom

If you had one piece of advice you could tell yourself when you first started learning powershell, what would it be?

reddit.com
u/Ajamaya — 4 days ago

Working With PIM Role Activation

In an effort to make my life a little bit better, I've built a script that I can use to activate the 5 or 6 PIM roles all at once, instead of having to activate them one by one online

The only hurdle left for me to figure out is a better way to get each roles Maximum duration, as my current solution, adding CSV data directly in the file, may not always be accurate, but I haven't been able to map the policies I'm getting when running

Get-MgPolicyRoleManagementPolicy -Filter "scopeId eq '/' and scopeType eq 'DirectoryRole'"

And the RoleTemplteID's I'm getting from

Get-MgDirectoryRole -all
reddit.com
u/seriald — 4 days ago

Create scheduled task to run at logon and repeat indefinitely every 3 minutes?

I have this:

$TaskName = "Automation"

$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument '-ExecutionPolicy Bypass C:\Automation\Automation.ps1'

$Trigger = New-ScheduledTaskTrigger -AtLogOn

$Principal = New-ScheduledTaskPrincipal -GroupID "Builtin\USERS" -RunLevel Highest

$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable

Register-ScheduledTask -TaskName $TaskName -Action $Action -Trigger $Trigger -Principal $Principal -Settings $Settings -Force

However, I need it to run again every 3 minutes after login. I tried doing

$Trigger = New-ScheduledTaskTrigger -AtLogOn -RepeatIndefinitely -RepetitionInterval (New-TimeSpan -Minutes 3)

but that didn't work. Anyone have any suggestions?

reddit.com
u/LordLoss01 — 4 days ago

What is the best resource in 2026 to learn PowerShell scripting?

I want to learn advanced powershell scripting but I have French still see very old resources. What sources would you recommend?

reddit.com
u/Optimist1975 — 5 days ago

Issue with powershell script running on N-able

I'm not a powershell expert by any stretch, but I can script kiddie my way around fairly well. N-able has a utility for executing a powershell script on a client, but it isn't working. Basically it is failing to write an out-file to a shared network server. It executes locally on my machine without any issues. Any pointers would be much appreciated!

Trying to execute the following code:

# $OutputFile = "\\realhostnamegoeshere\common\output_log.txt"

$OutputFile = "c:\output_log.txt"

$ComputerName = $env:COMPUTERNAME

Get-WinEvent -FilterHashtable @{LogName='System'; Id=1808} -ErrorAction SilentlyContinue |

Select-Object @{Name='ComputerName'; Expression={$ComputerName}}, TimeCreated, Id, Message |

Out-File -FilePath $OutputFile -Append

And getting this error:

Out-File : Access to the path '\\slsindfps02\common\output_log.txt' is denied.

reddit.com
u/Limp-Leather-241 — 4 days ago

Why if($path|Test-Path){'do something'} is considered a bad choice?

I came across a recommendation that if($path|Test-Path){'do something'} (which I used to most of the time) is considered a bad choice, while if(Test-Path -path $path){'do something'} is the best practice. Why so?

As I google it, it answers like that:

> The recommendation stands because using the pipeline ($path|Test-Path) introduces massive performance overhead and creates a dangerous blind spot where your script can fail silently if a variable is empty.

> While both statements return a true/false value, passing the path as a direct parameter is safer, cleaner, and significantly faster.

So, should I completely abandon the if($path|Test-Path){'do something'} syntax?

And, moreover, if(([IO.DirectoryInfo]$path).Exists -or ([IO.FileInfo]$path).Exists){'do something'} makes the complete loser of the Test-Path?

Edit 2

To be clear, this is what I was doing yesterday (let's say, at the request of a friend), and what has finally motivated me to search for the question and to ask it here. There could be easily [tens] thousands of Test-Path items (simplified):

$time = [diagnostics.stopwatch]::StartNew()

if(-not $args){
    'no input parameters have been passed; nothing to do here, exiting...'
    sleep -second 3
    exit
}

'input parameters:'|Write-Host -f Yellow
'[0] current source path : {0}' -f $args[0];$sourcePath = $args[0]
'[1] current target path : {0}' -f $args[1];$targetPath = $args[1]

$list = Get-Item -path 'd:\copy_files_from_list.txt'
$filenames = [IO.File]::ReadLines($list)|foreach{$_}
''
'filenames list:'|Write-Host -f Yellow
for ($i=0;$i -lt $filenames.count;$i++){
    '[{0}] : {1}' -f $i,$filenames[$i]|Write-Host -f Green
}
''
'find and copy files from a filenames list into a destination preserving the directory structure'
'phase 1 : files are somewhere within the disk where the $sourcePath resides:'|Write-Host -f Yellow
$path = (Get-Item $sourcePath).PSDrive.Root
$files = Get-ChildItem -path $path -file -force -recurse -EA:silent|Where{$_.Name -in $filenames}
foreach ($file in $files){
    # [IO.Path]::GetRelativePath($path,$file)
    $suffix = [IO.Path]::GetRelativePath($path,$file)
    $destination = [IO.Path]::combine($targetPath,$suffix)
    $destinationPath = ([IO.FileInfo]$destination).Directory
    # Test-Path here is now replaced with [IO.Directory]::Exists()
    if(-not [IO.Directory]::Exists($destinationPath)){
        New-Item $destinationPath -type directory -force|Out-Null
    }
    '{0} >> {1}' -f $file.FullName,$destination
    Copy-Item $file $destination -force
}
'{0} files have been copied' -f $files.count
$firstPhase =  $time.Elapsed
'{0:mm\:ss\.fff} : the first phase timing' -f $firstPhase
''
'...'
''
# finalizing
$time.Stop()
'{0:mm\:ss\.fff} : the total timing by {1}' -f $time.Elapsed,$MyInvocation.MyCommand.Name
sleep -second 33
reddit.com
u/ewild — 5 days ago

Get-Help Informations missing

I'm in the middle of decorating some older functions with HelpMessages / Get-Help Infos. Somehow i can't get the output to work without adding "junk information". Specifically Aliases, Parameter-Sets and Default Values:

This Function:

function Test-FunctionHelp {

    <#
    .SYNOPSIS
    .DESCRIPTION
    .PARAMETER TestParameter
    .EXAMPLE
    Test-FunctionHelp -TestParameter "Parameter"
    #>

    [CmdletBinding()]
    [Alias('tfh')]

    param (
        [Parameter()]
        [Alias('ParameterAlias')]
        [string]$TestParameter
    )
}

Get-Help "Test-FunctionHelp" -Full

Outputs this Help:

NAME
    Test-FunctionHelp

SYNOPSIS
SYNTAX
    Test-FunctionHelp [[-TestParameter] <String>] [<CommonParameters>]


DESCRIPTION


PARAMETERS
    -TestParameter <String>

        Required?                    false
        Position?                    1
        Default value
        Accept pipeline input?       false
        Aliases
        Accept wildcard characters?  false

    <CommonParameters>
        This cmdlet supports the common parameters: Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer, PipelineVariable, and OutVariable. For more information, see
        about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216).

INPUTS

OUTPUTS

    -------------------------- EXAMPLE 1 --------------------------

    PS > Test-FunctionHelp -TestParameter "Parameter"


RELATED LINKS

While adding junk at the last part of of the Help Block like this:

function Test-FunctionHelp {

    <#
    .SYNOPSIS
    .DESCRIPTION
    .PARAMETER TestParameter
    .EXAMPLE
    Test-FunctionHelp -TestParameter "Parameter"
    .A
    #>

    [CmdletBinding()]
    [Alias('tfh')]

    param (
        [Parameter()]
        [Alias('ParameterAlias')]
        [string]$TestParameter
    )
}

Get-Help "Test-FunctionHelp" -Full

Outputs the expected Helpmessage:

NAME
    Test-FunctionHelp

SYNTAX
    Test-FunctionHelp [[-TestParameter] <string>] [<CommonParameters>]

PARAMETERS
    -TestParameter <string>

        Required?                    false
        Position?                    0
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      ParameterAlias
        Dynamic?                     false
        Accept wildcard characters?  false

    <CommonParameters>
        This cmdlet supports the common parameters: Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer, PipelineVariable, and OutVariable. For more information, see
        about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216).


INPUTS
    None

OUTPUTS
    System.Object

    -------------------------- EXAMPLE 1 --------------------------

    PS > Test-FunctionHelp -TestParameter "Parameter"

ALIASES
    tfh

REMARKS
    None

Is there anything i'm missing? It's not that big of a deal but i'm wondering why some things are not picked up properly without adding some junk into the Help-Block. Am i missing something particulary important in the help block?

Btw it doesn't matter at what point i add the "junk"

all of those examples work as intended:

    <#
    .SYNOPSIS
    .DESCRIPTION
    .PARAMETER TestParameter
    .EXAMPLE
    Test-FunctionHelp -TestParameter "Parameter"
    .A
    #>

    <#
    .A
    .SYNOPSIS
    .DESCRIPTION
    .PARAMETER TestParameter
    .EXAMPLE
    Test-FunctionHelp -TestParameter "Parameter"
    #>

    <#
    .SYNOPSIS
    .DESCRIPTION
    .PARAMETER TestParameter
    .EXAMPLE
    .A
    Test-FunctionHelp -TestParameter "Parameter"
    #>
reddit.com
u/xXFl1ppyXx — 5 days ago

RPC Errors running against computer list

Hi,

I have a script to check a few registry entries
When run at individual machines, the script returns results.
When running against a list of machines in a for-each loop, I get RPC errors.
I paused all the security agents with the same result.

I need some ideas from the hive brain, please, and thank you
edit: This script worked last year against all the servers.

reddit.com
u/network_dude — 6 days ago

End Task script is repeating back to me instead of executing

I have tried to make a script to close Webex when it reached a certain time but the CLI just repeats the command back to me instead of executing it. AI has no given me any useful suggestions so I am hoping someone on here could help me. Code is as follows:

Get-Process -Name "Webex" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Write-Host "Webex has been stopped." -ForegroundColor Green
reddit.com
u/Covid_Nipple420 — 6 days ago

Best Practical Way to Learn PowerShell for Cloud/M365 Administration

Hello everyone,

I recently acquired a few cloud certifications and I’m currently building my career in cloud and Microsoft technologies. At this stage, I’ve realized that PowerShell is a very important skill for the direction I want to take.

I’ve been trying to find videos and learning resources that can help me study PowerShell effectively, but so far I haven’t really found an approach that fully clicks for me.

What has helped me a bit is using AI to ask questions and then implementing the code and examples I get back. That approach has actually helped me grasp a few concepts better through practice.

My question is: what would you recommend for a beginner like me to learn PowerShell effectively without getting overwhelmed or burned out?

I’m not afraid to get my hands dirty and practice — I just want to learn in a way that is practical, structured, and sustainable long term.

For context, I currently work with Microsoft 365, Entra ID, SharePoint, and Azure administration.

Any advice, roadmaps, practice methods, labs, or learning resources would be greatly appreciated.

Thank you.

reddit.com
u/Imaginary_Rip2833 — 6 days ago

How to get retention policy on a soft-deleted mailbox via Powershell

We have thousands of users who’s mailboxes are soft-deleted/inactive since 2024. I’m trying to confirm which policy is responsible for this as the default is 30 days after an account is deleted.

Trying to read up on the MS documentation is confusing, but I can get the mailbox, get our purview policies, legacy exchange policies etc but I can’t tell how to put them together to get what’s applied to a specific mailbox.

reddit.com
u/Murhawk013 — 4 days ago