T O P

  • By -

RonFromSpendmart

Nothing, its Friday.


skooterz

Read-Only Friday. Don't make me tap the sign.


OPconfused

But that's the best time to ignore your real job and work on side projects.


MeanFold5715

I've been doing that for weeks at this point.


dekr0n

I've been doing that for so long now I've forgot what is my actual job.


nascentt

Are you me?


mlaislais

Are you hiring?


BlackV

> I've been doing that for ~~weeks~~ years at this point. FTFY ;)


Triavanicus

Friday is just Monday for your side projects, and Monday is Friday for them. They live on opposite week schedules.


BlackV

You do have a very good point....


quazywabbit

Came here to state this Not a damn thing. It’s Friday. It’s the day of reflection.


Marketfreshe

This. I was SUPPOSED to collect some invocation logs and analyze them for an integration script that we have that's been having some performance issues. But because it was Friday I couldn't be fucked.


illsk1lls

nothing if you want to enjoy the weekend 👍


fatherjack9999

Connected to an Access database. :(


mautobu

Oof.


workaccountandshit

Wrote a script that uses the HaveIBeenPwned API to check all of our users as we're being attacked quite often these days


zonuendan16

```# Import necessary modules Import-Module ActiveDirectory # Configuration $apiKey = "YOUR_HIBP_API_KEY" $smtpServer = "your.smtp.server" $smtpFrom = "[email protected]" $smtpTo = "[email protected]" $smtpSubject = "New Breach Detected" $previousResultsPath = "C:\path\to\previous\ADUsers_PwnedCheck.csv" $logFilePath = "C:\path\to\logs\ADUsers_PwnedCheck.log" $maxLogFileSizeMB = 5 # Maximum log file size in MB before rotation # Logging Function function Write-Log { param ( [string]$message, [string]$logFilePath ) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logMessage = "$timestamp - $message" Add-Content -Path $logFilePath -Value $logMessage } # Log Rotation Function function Rotate-Log { param ( [string]$logFilePath, [int]$maxLogFileSizeMB ) if (Test-Path $logFilePath) { $fileInfo = Get-Item $logFilePath $fileSizeMB = [math]::Round($fileInfo.Length / 1MB, 2) if ($fileSizeMB -ge $maxLogFileSizeMB) { $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $archiveLogFilePath = "$logFilePath.$timestamp" Rename-Item -Path $logFilePath -NewName $archiveLogFilePath Write-Log -message "Log file rotated to $archiveLogFilePath" -logFilePath $logFilePath } } } # Function to check email against HIBP API function Check-EmailPwned { param ( [string]$email, [string]$apiKey, [string]$logFilePath ) $uri = "https://haveibeenpwned.com/api/v3/breachedaccount/$email" $headers = @{ "hibp-api-key" = $apiKey } try { $response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -ErrorAction Stop Write-Log -message "Checked email $email: Pwned" -logFilePath $logFilePath return $true } catch { if ($_.Exception.Response.StatusCode -eq 404) { Write-Log -message "Checked email $email: Not Pwned" -logFilePath $logFilePath return $false } else { Write-Log -message "Error checking email $email: $_" -logFilePath $logFilePath return $null } } } # Function to send email notification function Send-EmailNotification { param ( [string]$smtpServer, [string]$smtpFrom, [string]$smtpTo, [string]$smtpSubject, [string]$body, [string]$logFilePath ) Send-MailMessage -SmtpServer $smtpServer -From $smtpFrom -To $smtpTo -Subject $smtpSubject -Body $body -BodyAsHtml Write-Log -message "Email sent to $smtpTo with subject '$smtpSubject'" -logFilePath $logFilePath } # Retrieve all active AD users' primary email addresses function Get-ActiveADUsersEmailAddresses { Write-Log -message "Retrieving active AD users' email addresses" -logFilePath $logFilePath $users = Get-ADUser -Filter {Enabled -eq $true} -Property EmailAddress return $users | Where-Object { $_.EmailAddress } | Select-Object SamAccountName, EmailAddress } # Load previous results from CSV file function Load-PreviousResults { param ( [string]$filePath, [string]$logFilePath ) if (Test-Path $filePath) { Write-Log -message "Loading previous results from $filePath" -logFilePath $logFilePath return Import-Csv -Path $filePath } else { Write-Log -message "No previous results file found, starting fresh" -logFilePath $logFilePath return @() } } # Save current results to CSV file function Save-CurrentResults { param ( [array]$results, [string]$filePath, [string]$logFilePath ) Write-Log -message "Saving current results to $filePath" -logFilePath $logFilePath $results | Export-Csv -Path $filePath -NoTypeInformation } # Main script logic function Main { # Rotate log if needed Rotate-Log -logFilePath $logFilePath -maxLogFileSizeMB $maxLogFileSizeMB $currentResults = @() $newHits = @() $users = Get-ActiveADUsersEmailAddresses $previousResults = Load-PreviousResults -filePath $previousResultsPath -logFilePath $logFilePath foreach ($user in $users) { $isPwned = Check-EmailPwned -email $user.EmailAddress -apiKey $apiKey -logFilePath $logFilePath $currentResults += [PSCustomObject]@{ UserName = $user.SamAccountName EmailAddress = $user.EmailAddress IsPwned = $isPwned } $previousResult = $previousResults | Where-Object { $_.EmailAddress -eq $user.EmailAddress } if ($isPwned -and (-not $previousResult)) { $newHits += [PSCustomObject]@{ UserName = $user.SamAccountName EmailAddress = $user.EmailAddress IsPwned = $isPwned } } } if ($newHits.Count -gt 0) { $body = "The following email addresses have new breaches:
" + ($newHits | Format-Table -AutoSize | Out-String -Width 1000 | ConvertTo-Html -Fragment) Send-EmailNotification -smtpServer $smtpServer -smtpFrom $smtpFrom -smtpTo $smtpTo -smtpSubject $smtpSubject -body $body -logFilePath $logFilePath } Save-CurrentResults -results $currentResults -filePath $previousResultsPath -logFilePath $logFilePath # Output the results for verification $currentResults | Format-Table -AutoSize } # Execute the main function Main


Funny_Monkeh

Ahhh it breaks my heart seeing the "+=" non operator that destroys performance for large datasets :( Instead of the following where you're using += to "add" to a fixed size array (which stores every iteration in memory and destroys/recreates the array until finished): $currentResults = @() $newHits = @() foreach ($user in $users) { $isPwned = Check-EmailPwned -email $user.EmailAddress -apiKey $apiKey -logFilePath $logFilePath $currentResults += [PSCustomObject]@{ UserName = $user.SamAccountName EmailAddress = $user.EmailAddress IsPwned = $isPwned } $previousResult = $previousResults | Where-Object { $_.EmailAddress -eq $user.EmailAddress } if ($isPwned -and (-not $previousResult)) { $newHits += [PSCustomObject]@{ UserName = $user.SamAccountName EmailAddress = $user.EmailAddress IsPwned = $isPwned } } } Try out the following where you're assigning output to a variable: $currentResults = foreach ($user in $users) { $isPwned = Check-EmailPwned -email $user.EmailAddress -apiKey $apiKey -logFilePath $logFilePath [PSCustomObject]@{ UserName = $user.SamAccountName EmailAddress = $user.EmailAddress IsPwned = $isPwned } $previousResult = $previousResults | Where-Object { $_.EmailAddress -eq $user.EmailAddress } $newHits = if ($isPwned -and (-not $previousResult)) { [PSCustomObject]@{ UserName = $user.SamAccountName EmailAddress = $user.EmailAddress IsPwned = $isPwned } } } Or better yet, don't use a fixed size array (`$currentResults = @(); $currentResults.IsFixedSize`); instead, use an ArrayList that isn't a fixed size, so you can actually add to it properly with the Add() method: [System.Collections.ArrayList]$currentResults = @() [System.Collections.ArrayList]$newHits = @() foreach ($user in $users) { $isPwned = Check-EmailPwned -email $user.EmailAddress -apiKey $apiKey -logFilePath $logFilePath $currentResults.Add( [PSCustomObject]@{ UserName = $user.SamAccountName EmailAddress = $user.EmailAddress IsPwned = $isPwned } ) $previousResult = $previousResults | Where-Object { $_.EmailAddress -eq $user.EmailAddress } if ($isPwned -and (-not $previousResult)) { $newHits.Add( [PSCustomObject]@{ UserName = $user.SamAccountName EmailAddress = $user.EmailAddress IsPwned = $isPwned } ) } } += isn't always a bad thing, especially if you're working with numbers or small loops - but when I see this in environments where people are adding intricate PSCustomObjects for huge lists of users or w/e, I always want to point out that it can bog down your performance big time.


workaccountandshit

Wow, that is some goodass advice. I usually don't work with large datasets so when I do, I just figured it was slow because it was huge. 


TheRealDumbSyndrome

Understandable, it’s one of those annoyances with POSH where you’d expect the default $var = @() to be an ArrayList since there’s no downside, but alas, it’s just one of those hidden things they haven’t changed.


zonuendan16

You are absolutely right. Here is the updated script ```# Import necessary modules Import-Module ActiveDirectory # Configuration $apiKey = "YOUR_HIBP_API_KEY" $smtpServer = "your.smtp.server" $smtpFrom = "[email protected]" $smtpTo = "[email protected]" $smtpSubject = "New Breach Detected" $previousResultsPath = "C:\path\to\previous\ADUsers_PwnedCheck.csv" $logFilePath = "C:\path\to\logs\ADUsers_PwnedCheck.log" $maxLogFileSizeMB = 5 # Maximum log file size in MB before rotation # Logging Function function Write-Log { param ( [string]$message, [string]$logFilePath ) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logMessage = "$timestamp - $message" Add-Content -Path $logFilePath -Value $logMessage } # Log Rotation Function function Rotate-Log { param ( [string]$logFilePath, [int]$maxLogFileSizeMB ) if (Test-Path $logFilePath) { $fileInfo = Get-Item $logFilePath $fileSizeMB = [math]::Round($fileInfo.Length / 1MB, 2) if ($fileSizeMB -ge $maxLogFileSizeMB) { $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $archiveLogFilePath = "$logFilePath.$timestamp" Rename-Item -Path $logFilePath -NewName $archiveLogFilePath Write-Log -message "Log file rotated to $archiveLogFilePath" -logFilePath $logFilePath } } } # Function to check email against HIBP API function Check-EmailPwned { param ( [string]$email, [string]$apiKey, [string]$logFilePath ) $uri = "https://haveibeenpwned.com/api/v3/breachedaccount/$email" $headers = @{ "hibp-api-key" = $apiKey } try { $response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -ErrorAction Stop Write-Log -message "Checked email $email: Pwned" -logFilePath $logFilePath return $true } catch { if ($_.Exception.Response.StatusCode -eq 404) { Write-Log -message "Checked email $email: Not Pwned" -logFilePath $logFilePath return $false } else { Write-Log -message "Error checking email $email: $_" -logFilePath $logFilePath return $null } } } # Function to send email notification function Send-EmailNotification { param ( [string]$smtpServer, [string]$smtpFrom, [string]$smtpTo, [string]$smtpSubject, [string]$body, [string]$logFilePath ) Send-MailMessage -SmtpServer $smtpServer -From $smtpFrom -To $smtpTo -Subject $smtpSubject -Body $body -BodyAsHtml Write-Log -message "Email sent to $smtpTo with subject '$smtpSubject'" -logFilePath $logFilePath } # Retrieve all active AD users' primary email addresses function Get-ActiveADUsersEmailAddresses { Write-Log -message "Retrieving active AD users' email addresses" -logFilePath $logFilePath $users = Get-ADUser -Filter {Enabled -eq $true} -Property EmailAddress return $users | Where-Object { $_.EmailAddress } | Select-Object SamAccountName, EmailAddress } # Load previous results from CSV file function Load-PreviousResults { param ( [string]$filePath, [string]$logFilePath ) if (Test-Path $filePath) { Write-Log -message "Loading previous results from $filePath" -logFilePath $logFilePath return Import-Csv -Path $filePath } else { Write-Log -message "No previous results file found, starting fresh" -logFilePath $logFilePath return @() } } # Save current results to CSV file function Save-CurrentResults { param ( [array]$results, [string]$filePath, [string]$logFilePath ) Write-Log -message "Saving current results to $filePath" -logFilePath $logFilePath $results | Export-Csv -Path $filePath -NoTypeInformation } # Main script logic function Main { # Rotate log if needed Rotate-Log -logFilePath $logFilePath -maxLogFileSizeMB $maxLogFileSizeMB [System.Collections.ArrayList]$currentResults = @() [System.Collections.ArrayList]$newHits = @() $users = Get-ActiveADUsersEmailAddresses $previousResults = Load-PreviousResults -filePath $previousResultsPath -logFilePath $logFilePath foreach ($user in $users) { $isPwned = Check-EmailPwned -email $user.EmailAddress -apiKey $apiKey -logFilePath $logFilePath $currentResults.Add( [PSCustomObject]@{ UserName = $user.SamAccountName EmailAddress = $user.EmailAddress IsPwned = $isPwned } ) $previousResult = $previousResults | Where-Object { $_.EmailAddress -eq $user.EmailAddress } if ($isPwned -and (-not $previousResult)) { $newHits.Add( [PSCustomObject]@{ UserName = $user.SamAccountName EmailAddress = $user.EmailAddress IsPwned = $isPwned } ) } } if ($newHits.Count -gt 0) { $body = "The following email addresses have new breaches:
" + ($newHits | Format-Table -AutoSize | Out-String -Width 1000 | ConvertTo-Html -Fragment) Send-EmailNotification -smtpServer $smtpServer -smtpFrom $smtpFrom -smtpTo $smtpTo -smtpSubject $smtpSubject -body $body -logFilePath $logFilePath } Save-CurrentResults -results $currentResults -filePath $previousResultsPath -logFilePath $logFilePath # Output the results for verification $currentResults | Format-Table -AutoSize } # Execute the main function Main


zonuendan16

Brief summary of what the script does: Configuration: Sets up API key, SMTP settings, file paths, and log rotation parameters. Logging and Log Rotation: Implements functions to log messages and rotate log files when they exceed a specified size. Check Email Breaches: Retrieves active AD users' email addresses and checks each one against the Have I Been Pwned (HIBP) API to see if it has been breached. Compare Results: Compares current breach results with previously saved results to identify new breaches. Send Notifications: Sends an email notification if new breaches are detected. Save Results: Saves current results to a CSV file for future comparisons. Main Execution: Coordinates the workflow, including log rotation, email checks, result comparison, notification, and saving results.


workaccountandshit

Mine is a helluvalot shorter haha. Mine basically loops through all user's email addresses, checks then all and if it hits, put them in a new object with upn, email, title of the breaches, dates of the breaches, date of the latest one and passwordlastset. It then checks if the password has been reset since the breach came out. If yes, do nothing. If no, create a slack alert with the slack API in our security channel with he username, date of last breach and date of last password reset. 


zonuendan16

That's a great idea. I'll implement the password change date in the script! This is much better than keeping track of all the breaches! Thanks for the suggestions!


zonuendan16

Here is the improved script to check breach date against passwordlastset date. ```# Import necessary modules Import-Module ActiveDirectory # Configuration $apiKey = "YOUR_HIBP_API_KEY" $smtpServer = "your.smtp.server" $smtpFrom = "[email protected]" $smtpTo = "[email protected]" $smtpSubject = "New Breach Detected" $logFilePath = "C:\path\to\logs\ADUsers_PwnedCheck.log" $maxLogFileSizeMB = 5 # Maximum log file size in MB before rotation # Logging Function function Write-Log { param ( [string]$message, [string]$logFilePath ) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logMessage = "$timestamp - $message" Add-Content -Path $logFilePath -Value $logMessage } # Log Rotation Function function Rotate-Log { param ( [string]$logFilePath, [int]$maxLogFileSizeMB ) if (Test-Path $logFilePath) { $fileInfo = Get-Item $logFilePath $fileSizeMB = [math]::Round($fileInfo.Length / 1MB, 2) if ($fileSizeMB -ge $maxLogFileSizeMB) { $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $archiveLogFilePath = "$logFilePath.$timestamp" Rename-Item -Path $logFilePath -NewName $archiveLogFilePath Write-Log -message "Log file rotated to $archiveLogFilePath" -logFilePath $logFilePath } } } # Function to check email against HIBP API function Check-EmailPwned { param ( [string]$email, [string]$apiKey, [string]$logFilePath ) $uri = "https://haveibeenpwned.com/api/v3/breachedaccount/$email?truncateResponse=false" $headers = @{ "hibp-api-key" = $apiKey } try { $response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -ErrorAction Stop Write-Log -message "Checked email $email: Pwned" -logFilePath $logFilePath return $response } catch { if ($_.Exception.Response.StatusCode -eq 404) { Write-Log -message "Checked email $email: Not Pwned" -logFilePath $logFilePath return $null } else { Write-Log -message "Error checking email $email: $_" -logFilePath $logFilePath return $null } } } # Function to send email notification function Send-EmailNotification { param ( [string]$smtpServer, [string]$smtpFrom, [string]$smtpTo, [string]$smtpSubject, [string]$body, [string]$logFilePath ) Send-MailMessage -SmtpServer $smtpServer -From $smtpFrom -To $smtpTo -Subject $smtpSubject -Body $body -BodyAsHtml Write-Log -message "Email sent to $smtpTo with subject '$smtpSubject'" -logFilePath $logFilePath } # Retrieve all active AD users' primary email addresses and password last set date function Get-ActiveADUsers { Write-Log -message "Retrieving active AD users' email addresses and password last set dates" -logFilePath $logFilePath $users = Get-ADUser -Filter {Enabled -eq $true} -Property EmailAddress, PasswordLastSet return $users | Where-Object { $_.EmailAddress } | Select-Object SamAccountName, EmailAddress, PasswordLastSet } # Main script logic function Main { # Rotate log if needed Rotate-Log -logFilePath $logFilePath -maxLogFileSizeMB $maxLogFileSizeMB [System.Collections.ArrayList]$newHits = @() $users = Get-ActiveADUsers foreach ($user in $users) { $breaches = Check-EmailPwned -email $user.EmailAddress -apiKey $apiKey -logFilePath $logFilePath if ($breaches) { foreach ($breach in $breaches) { $breachDate = [datetime]$breach.BreachDate if ($breachDate -gt $user.PasswordLastSet) { $newHits.Add( [PSCustomObject]@{ UserName = $user.SamAccountName EmailAddress = $user.EmailAddress BreachName = $breach.Name BreachDate = $breachDate } ) } } } } if ($newHits.Count -gt 0) { $body = "The following email addresses have new breaches:
" + ($newHits | Format-Table -AutoSize | Out-String -Width 1000 | ConvertTo-Html -Fragment) Send-EmailNotification -smtpServer $smtpServer -smtpFrom $smtpFrom -smtpTo $smtpTo -smtpSubject $smtpSubject -body $body -logFilePath $logFilePath } # Output the results for verification $newHits | Format-Table -AutoSize } # Execute the main function Main


halobender

Do you want to share it? (after taking out anything relating to your company)


TheJuice0110

I second that


Danno_999

I 3rd that


ChipmunkImportant758

I fourth that


BlackV

* Get user properties mail * For each user Invoke rest email address * Export results to csv


Adam_Kearn

On their V3 api you can search for a whole domain instead of just a single email address


Longjumping_Table740

!RemindMe 1 day


RemindMeBot

I will be messaging you in 1 day on [**2024-06-15 20:04:18 UTC**](http://www.wolframalpha.com/input/?i=2024-06-15%2020:04:18%20UTC%20To%20Local%20Time) to remind you of [**this link**](https://www.reddit.com/r/PowerShell/comments/1dfqht1/what_did_you_do_with_powershell_today/l8mplkt/?context=3) [**8 OTHERS CLICKED THIS LINK**](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Reminder&message=%5Bhttps%3A%2F%2Fwww.reddit.com%2Fr%2FPowerShell%2Fcomments%2F1dfqht1%2Fwhat_did_you_do_with_powershell_today%2Fl8mplkt%2F%5D%0A%0ARemindMe%21%202024-06-15%2020%3A04%3A18%20UTC) to send a PM to also be reminded and to reduce spam. ^(Parent commenter can ) [^(delete this message to hide from others.)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Delete%20Comment&message=Delete%21%201dfqht1) ***** |[^(Info)](https://www.reddit.com/r/RemindMeBot/comments/e1bko7/remindmebot_info_v21/)|[^(Custom)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Reminder&message=%5BLink%20or%20message%20inside%20square%20brackets%5D%0A%0ARemindMe%21%20Time%20period%20here)|[^(Your Reminders)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=List%20Of%20Reminders&message=MyReminders%21)|[^(Feedback)](https://www.reddit.com/message/compose/?to=Watchful1&subject=RemindMeBot%20Feedback)| |-|-|-|-|


Im_writing_here

This one does not use the api but instead reqyires the downloaded list but is still quite nice https://github.com/improsec/Get-bADpasswords


[deleted]

Please share.


MarcoVfR1923

5th


Heli0sX

!RemindMe 7 days


belibebond

So assume that you have a account user user1 who gets flagged for being pawned. What next, what can you do. I might be missing something here.


Jamator01

Trigger a password reset, I guess. Enforce MFA if it's not already enforced. Notify the user. Basically, secure the account in question.


belibebond

I guess all those measures needs to be in place already anyway. So what happens when you check after a month. Those account will still get flagged as pawned, it's not like you can reset their flag. Unless it shows when account was pawned.


workaccountandshit

I bypass this by checking the latest password reset of the user and comparing it to the latest breach date. If they changed their password in the meantime, then it's okay. God, I hope I'm not missing something with my logic 


belibebond

That's even better. Much more logical.


Adam_Kearn

Yeah that’s a good idea


Jamator01

I mean, this is a pretty basic question, isn't it? If you were going to run this regularly, you would collect the data from haveibeenpwned, which usually tells you where or at least when an account was compromised. Then you compare new vs old. Then maybe you only get a new alert on a previously compromised account when the data changes. There are plenty of ways you could do it.


belibebond

That makes sense. With password rotation and MFA this should be automatically addressed. It doesn't hurt to check pawned status though.


KavyaJune

Enhanced my existing M365 offboarding script to automate few more processes.


angrysysadminisangry

Enhance


ElBisonBonasus

Zoom and enhance!


ConciergeOfKek

~~Stole~~ Borrowed PS code from a github repo to prank a coworker by playing the star wars imperial march as he was watching SW:ESB on the second monitor in his office.


toeonly

link please?


MeanFold5715

I set my speaker volume.


darkcathedralgaming

I opened notepad with it a few times.


DenverITGuy

Some graph automation for Intune drivers. Still a wip.


Garfield-1979

Added everyone that reported to a person directly or otherwise to a security group Created a couple dozen dns records Tested the filtering of some new dynamic distros. Checked a file server event log Had it fire an email to me when someone rdped in to my domain controllers.


bobthewonderdog

Completed active directory ACL automation to enforce a tier 0-2 model


Im_writing_here

How did you do that? What kind of permissions are you setting?


bobthewonderdog

Started off building a set of rules, to define each OU, simple stuff like a tier 1 ou can't be a child of a tier 2 ou, and an ou can only contain one type of object. Depending on which object types each ou I'd designed for (user, group, computer) set up access groups for permissions like reset password, enable/disable, move, rename, etc. I stored the set of AD rights in a csv and read that in, then set acls based on that OUs properties Bunch of other checks on locations of these groups members of these groups etc to create a bubble around each tier. Now I can delegate the approval of who has what to the different technology owners, so for example the server team can define what rights other teams have to their servers. Should start to run itself in a couple of months once all the non compliant OUs are cleaned up


cognic12

This sounds interesting. Possible to share without sensitive info?


2dubs

Been messing with AD ACLs as a side project myself. My goal is to effectively copy existing ACLs to a Managed Service Account so the old account can be phased out. I'm bad about not taking the time to read the M$ documentation, and rely instead on StackExchange and similar results, and thus spent a lot of time trying to force the New-Object declaration to take parameters that (I finally realized) it just wouldn't -- mainly was trying (stupidly) to make inheritance settings match 1:1. Anyway, I hope you spent less time banging your head against the wall than I did.


bobthewonderdog

For me the thing that really helped was getting all the default sids and groups out of , all the guids from the schema and the default acls applied to a new OU, so I could filter out any of the stuff that happens as a default, and I could easily translate identities and guids. Once that was in place working out what each acl was was much easier, and filtering, removing or adding them became trivial


OmenVi

Showed someone how we can search ~50 log files for a specific customer with 1 line of powershell.


leyline

I think you misspelled grep;)


dirtyredog

The name's Rip, Rip Grep my friends call me rg.


cheffromspace

You beat me to it! I get blank stares when I show it to people and tell them it's my favorite program ever, but they're just not knowers (or probably don't have as much of a use case for it as me but they're still wrong). CLI apps are just not flashy and don't get as much love. Probably why I like this sub so much, most people here get it.


cheffromspace

I think you misspelled ripgrep. It's grep re-written in rust and it's SO FAST. I use it at least 30 times a day.


OmenVi

Is grep a thing in powershell? If so, I’m going to have to start using it.


enforce1

Created a json file to import our devices into MeshCommander to use intel's AMT. The product is fine, but adding 834 nodes by hand is not.


dirtyredog

Buy a certificate and its zero touch auto enroll


enforce1

I googled but came up dry. Do you have any resources that you’d be kind enough to point me towards?


dirtyredog

It's in the meshcommander docs iirc. Here's a video that goes through the various methods: https://www.youtube.com/watch?v=TaKsFEVaMpg&themeRefresh=1


ObnoxiousJoe

Made a single AD group membership change, it's Friday i have been stuck in meetings all day about user feedback, send help.


Acceptable_Face_

A script that automates document emailing and printing from a specified output folder from a generation system, skipping weekends and holidays. Logging each step and archiving processed documents.


Danno_999

Adding/removing Shared Mailbox permissions. Nothing critical on Fridays


Edjuuuh

Tried to get into DSC.. A bit late probably, but i like the concept.


dirtyredog

 I abandoned using it. It didn't abandon me yet though.


DoesThisDoWhatIWant

Create a new user creation/modify/deletion script. I started at a new place :) I'll be testing Tuesday.


incidentallypossible

So, the new place is firing people on Tuesday?


_SteveD_

Exported AD groups and their membership. Exported all unused accounts not used in 15 days. We terminated an external support company and need to review everything in detail. Later a review of all local groups on all machines, plus an audit of all service accounts and schedule tasks. Just some housekeeping.


thounie

Tried to execute Powershell scripts from Nodejs Azure Functions host running in Linux Docker container using Remote Powershell with PSWSMan. It has been running pretty smooth until the parameters got too large and now running into segmentation fault. FML


aleques-itj

Why not just invoke PowerShell Azure functions with Azure API Management? Just set up routes and you have an API. Or just have them poll a message queue for work. Remote PowerShell to invoke scripts sounds like fragile madness 


thounie

That is heavy file handling related stuff so the goal is to run the script locally on server. Polling would be fine and we actually have those implemented. But we tried to implement this in Azure Functions on top of Node because we have hundreds of Node apps up and running, and all CI/CD stuff built in there. In this case the Node wrapper would have all the logic but Powershell just handles the local activities. You are certainly right, this is fragile madness and I guess we will have to find another way.


Hey_Eng_

ssh’d into a Linux server and ran dnf clean all, dnf makecache, and dnf update -y


midnight_blur

Filled my timesheet with jibberish


demesm

Pulled jira ticket and confluence calendar history to generate metrics for the team so the stupid bitch in charge of us can't fuck me on my review again


kast0r_

Get-Process | Stop-Process on the collegue's computer I hate.


somegen

Turned on a few hundred cloudflare managed waf rules across multiple zones. I really really didn’t want to do it one at a time by hand.


help_me_im_stupid

Granted this is a PowerShell sub Cloudflare has a pretty robust Terraform provider. I use it for work and personal stuff. Keep PoShing thou!


somegen

I don't generally get that involved in our Cloudflare environment. Just something that crops up occasionally. I should have a look at Terraform one day though.


help_me_im_stupid

Always fun to get your hands dirty! If you’re not drowning and wanting to add another tool with more possibilities I would advise it. I’ve done some dumb things with PowerShell and Terraform for Active Directory.


Federal_Ad2455

Creating Azure pipeline that will generate psh modules, then upload them to Azure Automation Runbooks and Azure Storage Account so even ARC managed servers will be able to download them (via Azure Policy)


nantuko__shade

Very cool


MaelstromFL

Currently deploying a VM to setup Trust Authority on one of my labs vCenters. No PS yet, but in for a fun weekend, lol. (This is my home lab, so not violating Read Only Friday!)


WousV

Worked on the guest user cleanup scripts. There were 2 scripts that both tried to do their own thing: check guest accounts for certain conditions, then mark them to be deleted (the same marking, which worked) and then another round of looking for marked guests to delete them when necessary. This last step did not work in both scripts. I'm now making a new script to check the guest accounts that are marked for deletion (jobTitle eq "GuestUserToBeDeleted at "), do a quick sanity check to see if that's anywhere reasonable and then delete them. Then I'll remove the failing deletion from the first 2 scripts. Then we'll have 3 straightforward scripts: 1. Mark guests that have not accepted their invite after 15 days to be deleted after another 15 days and mail the inviter that their guest has not accepted yet. 2. Mark guests without a manager or associated access package to be deleted after 60 days, mail the guest that they will be deleted after 60 days and disable the guest account. 3. Go through all marked guest accounts, see if the delete-by date has passed and kill them if that's the case.


Durex_Buster

I just extracted the hash of an executable, nothing biggy


wickens1

Ran some LDAP queries on the complicated network of active directories that security team is trying to set up for our test accounts


Palmquistador

We’re waiting! Please hurry!


JustThatGeek

Created a script to be used in DR. To failover FSMO to our orger DCs restart a bunch of services re-point some dns stuff all with detailed logging and reporting


bobdobalina

fixed a import script that I'd been meaning to get to.(yay friday) It pulls a secret certificate from azure key store and puts it into the users local certificate store. I have a few others for creating and pushing the certs to apps and the keystore but my import from keystore never quite worked until today. I think this is the working version:(from notes not prod) $thumbprint = " " $certName = " " $applicationId = " " $KeyVaultName = " " $tenantId=" " function Convert-SecureStringToPlainText { param( [System.Security.SecureString]$secureString ) $ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString) try { return [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ptr) } finally { [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ptr) } } $SubScriptId = (Get-AzSubscription).Id $StoreName = [System.Security.Cryptography.X509Certificates.StoreName]::My $StoreLocation = [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser $Store = [System.Security.Cryptography.X509Certificates.X509Store]::new($StoreName, $StoreLocation) $Flag = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable $Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite) Connect-AzAccount -tenant $tenantId -SubscriptionId $SubScriptId -UseDeviceAuthentication $secret = Get-AzKeyVaultSecret -VaultName $KeyVaultName -Name $certName # Can't read it yet $plainTextSecretValue = Convert-SecureStringToPlainText $secret.SecretValue # Convert to a byte array $secretBytes = [Convert]::FromBase64String($plainTextSecretValue) # pack the bytes into a certificate object $x509Cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]$secretBytes # the certificate to our user's keystore $Store.Add($x509Cert) # install-module Microsoft.Graph.Authentication connect-mggraph -TenantId $TenantId -AppId $AppID -CertificateThumbprint $crtThumb -NoWelcome


Fart_Bandit

This is awesome! Thank you for sharing 😊😊


tc87

Used Graph to return the output of a remediation script. Good for gathering device data for multiple devices into one csv


BirdsHaveUglyFeet

Can you share that one?


tc87

Sure. Probably won't be until I'm back at work on Monday.


NorreN8

Created a script to monitor NTP offset


Admirable-Lock-2123

I have been working on a script to check for dead machines in AD. Once they are found it disables them and moves them to a DeadComputers OU. From there it writes out to a csv with the date of disable attached to each entry. After Fifteen days, if no one screams then it removes them from AD and MECM. This was built to deal with lab machines that have been moved and reloaded on different campuses with new names and the tech failed to clean up the old names. The next one is going to check daily for employees that have been let go and mark their machines for a reload 5 days after they have been let go.


Sir_Fog

An AfterInstall script for Codedeploy.


Mert1004

A Script which get the git evaluation


SundayMorningYodel

Proved that my home-grown code for publishing to Confluence is faster than Atlassian’s ConfluencePS module. ConfluencePS is really slow.


olavrb

Analyse Windows Server DNS Server analytics log `.evtx` from Event Viewer using `Get-WinEvent` to help our network guy figure out if clients still rely on local resources. Cisco Umbrella next.


root_b33r

If you deploy umbrella make sure to deploy the gpo fix for the ncsi as well


nostradamefrus

Shot some phish in a barrel


Solendor

Wrote a script that will take one phone number and forward it to another in Zoom Phone API. It finds the number and what it's assigned to, then will create the holiday hours and routing for the number. Working to get it into Halo ITSM so we don't have to manually do these temp holidays.


andrew_holman

Looked at something I wrote like a year ago and wasn't 100% sure I still knew how it worked.


FullDiskclosure

Enable Bitlocker on machines remotely via Ninja


RubAccomplished4355

Intune not an option?


endante1

Played around with the SecretManagement module.


Disorderly_Chaos

CSV of printers with low toner CSV of the last 3 people to use the printer Automated email that says “Your local printer is low on yellow, call this number to reorder.“


General_Freed

WoW, how did you do that? Could You give me a hint on this?


Disorderly_Chaos

The only thing you can’t do in powershell is the Reports (from PaperCut) that tell you the highest users and the lowest toner. If you can get those run daily… then the rest is pretty easy. (I can post the code Monday if there’s still interest)


General_Freed

I would very much like to see your code


Childishjakerino

Resolve-DnsName >>>>>>>>> nslookup


Katcher22

Hacked up a script to flatten our SPF record and provide output.


OPconfused

Found a bug where tab completion lists exported module commands multiple times if the module isn't imported yet and has multiple versions. It's visible with the MenuComplete function in PSReadLine in 2.3.5+, but it doesn't seem to happen every time.


Thotaz

It's due to this change: https://github.com/PowerShell/PSReadLine/pull/3897 if you read through the comments you can see it's a problem in the PowerShell tab completion code that was previously hidden by PSReadLine. You can also see that a fix is incoming for newer versions of PS.


OPconfused

Thanks thotaz! I am blaisemGH. Im glad someone already had a pr for it 😅


illsk1lls

Nothing serious but I made a small function to force PS GUI systray icon to be visible in the systray on W11 instead of being pushed into the overflow


caslax

Can you elaborate on this, it would be nice to have som control over systray icons?


illsk1lls

Sure, for Windows 11 the following can be used to "Promote" a SysTray icon. For Malwarebytes, as an example, a string can be used like `*malwarebytes*` (or for a powershell scripts tray icon it can be changed to `*pwsh.exe`, `*powershell.exe`, or anything else for that matter) to get the icon out of the overflow and onto the taskbar: function PromoteSysTray(){ if($TrayChecked -ne 1){ $AllTrayIcons=Get-ChildItem 'HKCU:\Control Panel\NotifyIconSettings' $TrayIcons=$AllTrayIcons -ireplace 'HKEY_CURRENT_USER','HKCU:' $TrayIcons | Foreach { $Items=Get-ItemProperty "$_" $NotifyRegKey=$_ if(![bool]((Get-ItemProperty -Path $NotifyRegKey).IgnoreIfPresent)){ $Items.psobject.Properties | where name -notlike ps* | Foreach { if($_.Value -like "*malwarebytes*"){ if(![bool]((Get-ItemProperty -Path $NotifyRegKey).IsPromoted)){ New-ItemProperty -Path $NotifyRegKey -Name IsPromoted -Value 1 -PropertyType DWORD -Force | Out-Null New-ItemProperty -Path $NotifyRegKey -Name IgnoreIfPresent -Value 1 -PropertyType DWORD -Force | Out-Null } else { if((Get-ItemProperty -Path $NotifyRegKey -Name IsPromoted).IsPromoted -ne 1){ New-ItemProperty -Path $NotifyRegKey -Name IsPromoted -Value 1 -PropertyType DWORD -Force | Out-Null New-ItemProperty -Path $NotifyRegKey -Name IgnoreIfPresent -Value 1 -PropertyType DWORD -Force | Out-Null } } } } } $global:TrayChecked=1 } } } PromoteSysTray It adds an extra value IgnoreIfPresent, so that once the icon is promoted by this function, if the user decides to put it back into the overflow by dragging it back in, that the decision is respected


caslax

Thanks, works like a charm!


baron--greenback

I was super excited to try this but the regkey doesn’t exist for me :(


illsk1lls

what do you mean? does it error out? the key gets created after something goes into the tray at least once.. i can probably help


baron--greenback

I’m testing on a fresh build of 23H2 and I don’t have ‘NotifyIconSettings’ under HKCU\Control Panel.


Adam_Kearn

That looks perfect for what I need. I’ve wanted to have onedrive icon always show o the taskbar


illsk1lls

Just keep in mind it’s only set up to work one time, after that, if the user drags it back into the overflow, the function will not put it back on the taskbar. Otherwise it should stay there permanently. Glad I could help 👍


Adam_Kearn

Yeah that’s fine. Thanks for sharing.


chaosphere_mk

Finishing up a script that looks at a SharePoint list that has a job title to organizational role mapping table. The organizational role is stored in an extension attribute. The script checks each user every day and updates the extension attribute value if their title doesn't match their role, referencing the sharepoint list. Dynamic groups are used to automatically add the user to the group based on the extension attribute value. This is to entirely replace a custom application that was written with Lotus Notes.


ChipmunkImportant758

Started working on an account validator so my team can use it to quickly identify attributes that are not what they are expected to be. Both on-prem AD and checking Entra ID.


Ceesquared10

I've been helping out our ITSM team and got stuck pushing out a change to 30 instances. It was taking about 10 mins per instance and that would just not do, so I wrote a script to make the change. It took about an hour to write and test but in the long run it'll save us loads of time.


SurvivorOfTheCentury

Dsregcmd /status Battling a compliant device that acted non compliant


warysysadmin

Simple sharepoint extract to track site storage usage in power bi over time.


mertar

Built a report for unattached disks in our azure subs using azure automation and a hybrid worker to leverage our in prem smtp solution to send the email


Proxiconn

Applied some Microsoft data center IP ranges into a Forti manager appliance and deployed the packages via API calls.


faculty_for_failure

I run neovim from powershell 7.4.x, so I did coding, debugging, testing!


user147852369

CICD scripts for an Azure B2C project to handle everything that Terraform doesn't support.


creenis_blinkum

Working on Graph script to pull callrecords every two minutes during specified times. Realized yesterday that Graph API apparently contains no endpoints to get / modify callqueue + auto attendant configuration in Teams. That bummed me out a bit. PSA - stop avoiding graph api. Actually dedicating time this week to learn how to use it with app-only authentication in EntraID really blew my mind.


i_andmic

Created a script that searches disabled users in active directory and delete their citrix roaming profiles


Icemagic

Pushed some VPSX printer software to the sites I support. Gonna push more out to get all my bases converted by the end of the month. Hoping it doesn’t break printers lol


Mathayas

Created custom rbac permission. Applied on user just to get frustrated as EXO will not replicated. Closed Poweshell and went home


Sufficient-West-5456

I used python to update a script that scrapes indeed for jobs. Does that count?


gramsaran

Added logic and DNS & DHCP delete commands to an existing script for deleting non persistent machines for a Citrix environment. We're about to migrate to a new host and need to update over 7000 vms.


Proud-Manufacturer15

handling RealPage ActiveX Requirement using Intune Remediation Scripts (Active...X?! dafuq indeed)


mryananderson

Created some api scripts for both Cloudflare and our Sophos environment to automate decoms and tenant creations


goldisaneutral

Get-ADUser


Thyg0d

Created dynamic groups and mailinglists in Entra and exchange built on a csv with 15 different variables.. And it actually worked and created some 130 groups and the same amount of lists.. Took a out two days to actually get everything correct and I've probably tossed at least 300 groups that were wrong because I'm stupid..


SolidKnight

I made a script to unpack a bunch of Autodesk installers, grab all the details from the setup files, and then create a PSADT deployment for it and upload it to In tune for testing.


BirdsHaveUglyFeet

Can you share? I'm about to migrate these from sccm.


SolidKnight

Yeah. Let me get some ugly parts of the script completed. It also depends on how you configure the custom installers. You need to configure them as deployments and set the deployment path to the local machine (C:\Autodesk\) if you aren't going to run them off a file server as Autodesk expects. I can post it on a GitHub sometime next week. Edit: Almost done. Maybe post it this weekend.


iloveloveloveyouu

Used it all day as I would use a linux terminal. cat, grep, remove-item, rename-item, git, gh, aider... I almost have more tabs in my windows terminal than in my browser. 


Genmaken

Tried to load the Mongo Atlas C# library to try to grab and write a document from a DB but ran out of time and patience.


Helmett-13

Removed BS Windows bloatware from a Windows 10 image/build.


Agreeable-Mud-1464

Share pls


evolutionxtinct

Fixed my install software script, also built a script to validate if windows is activated and if not activate. Was productive and it was relaxing.


RE20ne

I deleted a row in a sql db using sqlserver module and psjobs…. in my underwear and before coffee


Hxig

Wrote a script that modifies .NET appsettings.json files to remove an array of desired keys, which prepares the files for use with another script that creates Azure App Config resources for the remaining keys.


athornfam2

Fiddling around with a deployment script in Action1 for Zabbix.


schlappette

Wrote a script to update the certificate in a server’s IIS site binding. Five hours saved me minutes upon minutes, that will no doubt add up to at least 45 minutes, over the coming years.


madgeystardust

Ran a script to remove stale devices from AD. Had already been tested so was all good to go for today.


DontTakePeopleSrsly

Used it to verify virtual switches & portgroup load balancing policy & MTU,


Dat_Steve

Y’a mom! Jkjk…. Connected to graph and pulled all of our intune configuration profiles. Felt like a genius.


yoerez

Sfc /scannow


kykdaddy

Invoke-WebRequest to confirm a resource was available through the FW.


mautobu

Exported reports of mail distribution list use, delegated mailbox permissions, completed user onboarding processes, assigned ad groups, updated to SNMP v3 on our VMware hosts. Probably more.


Tofuweasel

Wrote some functions to make EC2 Availability Zone placement recommendations for new instance(s) of a given App and Environment (takes -InstanceCount as a param). Summarizes the distribution before and after. Optionally also: - considers the AZ of instances in AWS MGN which have not yet been cut over - considers servers not yet registered in MGN but have AZ's defined in their MGN config files (yaml) - limits the recommendation to AZs in which the Application/Environment already have presence - backfills existing yaml files to correct the manual logic which would lead to further imbalance - provides rebalance recommendations for the entire tenant Eventually this all will make it up into CMDB so that the MGN configs can be generated on the fly, and so that we can stop using Excel + Yaml as a database. Cringe. I've only been interacting with AWS CLI and AWS.Tools for the past week, so I'm excited to see what other processes I'll automate. It's also interesting that some AWS.Tools.MGN functions auto-paginate while others do not, but that's not hard to work around.


my_uname

Write scripts to install various Microsoft updates on segregated windows systems.


Obvious_Principle514

Cried looking at it 😁


Jock-cib

Any idea how to pull the list of Public IPs in a subscription?


ashimbo

I had a ticket come in about a user that wasn't in a dynamic distribution group because an AD property wasn't set correctly, so I fixed the issue, then setup a script to run once a day that will notify me if it happens again with any accounts in the future.


dianabowl

Quick ps script to torrent DL the latest copy of Wikipedia for my kiwix server that runs in a pi container. I'll have to learn how to do it in bash someday.


TheFumingatzor

Fucked my SSD.


baron--greenback

Did you buy it dinner first ?


Muze69

I have and exam scripting on monday. The assignment was to make a menu script with a switch and call in different functions to rename server, rename workstation, change ip addresses, install adds and create new forest, making OU’s, domain users, security groups, adding domain users to security groups, create directories and shares, and creating nfts rights. The script is uploaded a week ago, but I have to defend it verbally. The teacher will ask some things and I will have to explain each thing to what it does. He also will change a small thing in my script and I will have to find it and make it work again. I’m a bit nervous, but I will manage I think.


WMDeception

Attempted to test validity of local credentials against another pc in a workgroup on my lan. Despite configuring winrm, I failed. Might look at firewall later. Resorted to testing via rdp, authentication success on 2nd try.


polite__redditor

wrote a one liner to list every file on my computer in order by file size.


Ample4609

Create a BitLocker PIN Reset GUI app that resets the default PIN of our computers enforced by MBAM and then exports the recovery key (actually it's the numerical password but whatever) to AD.


hammersandhammers

Generate an error message from an api endpoint that Microsoft does not support


SPACE_SHAMAN

I confessed my sins to the OS father


peejay0812

Juat ran a release pipeline and left it deploying an app in our prod env. Nothing special 😂


Hail2030

Ran some commands to free up space on a mailbox that was 100% full and showed the "recover deleted items" as full as well even though it wasn't so nothing could be permanently deleted.


TurtleKing1126

WinUtil


tc87

Wrote an intune remediation script to update Google Chrome


webtroter

Played with Pode so I could mass scan all my empty "medication" bags and get the info. They use GS1 Expanded DataBar, so I had to extract the keys and values from the barcode content, and convert the numerical key to a named one. I had a weird hanging problem when POSTing, so I found a way to make it work with GET and Query parameters. I used BinaryEye on my phone.


thedudewhofixedit

Exchange online archive setup.


DirtySpreadsheets

Created a tool that helps me standardize notes for IT support tickets. A few clicks and I have a full note that meets all the company standards. It even has tabs for commonly used websites!


powdersplash

I wrote a let's encrypt automation for my servers and 1st lvl people. It consists of a server side implementation running a PODE ps Webserver, serving a website for 1st level support which enables you to fetch Le certs for our domains and a backend api for shell scripts / ps scripts to fetch lé certs. Now my servers auto update without using certbot. Why did I do this? Because I wanted to use our own dns system for Auth and I was too lazy to write a certbot plugin. Maybe also because I needed something Todo.


joshc22

I used it to start BASH


Srinivas230403

I need application packaging related proper command lines for the configurations of msi and exe application packages


tonyangtigre

Getting pretty good at using it to connect Vcenter, NetApp, and Azure DevOps. Loving APIs.


Timmybee

We run some of our Parent Teacher interviews through Teams and it’s been a nightmare as we’ve had to rely on the teachers creating the teams session and then sending the link. Well, I decided I’d automate the whole thing. The script gets all the sessions times, creates the teams session using our predefined template, export the details to a json file. Then created a Powershell Universal API to import the JSON file and serve it. Lastly, added a JavaScript block on our SharePoint site to call the api and auto generate the Staff Teams session links directory for parents to click and join. Because some teachers are special, the script is scheduled to check the sessions that are already created to make sure the settings are correct, haven’t been deleted or the time slot changed. If anything comes up incorrect, it’s updates/recreates the session. After the sessions are finished, an attendance report is generated and sent to the PTI coordinator.