windows powershell
1193 TopicsProblem restoring deleted user with mggraph
Hello, I have done a few 365 migration and almost everytime there are some user data that has been missed in the migration. Earlier I solved this by restoring the 365 user in the source tenant to another domain using this msol script in powershell: Restore-MsolUser -UserPrincipalName email address removed for privacy reasons -Verbose Restore-MsolUser -UserPrincipalName email address removed for privacy reasons -Verbose -AutoReconcileProxyConflicts Restore-MsolUser -UserPrincipalName email address removed for privacy reasons -Verbose -AutoReconcileProxyConflicts -NewUserPrincipalName email address removed for privacy reasons I know it is not perfect but it worked well and saved a bunch of times. I have now done another migration now and got the same issue so I need to restore the users so we can access the data again and move it. BUT! I realized today that msol service is no more, so I am kinda stuck with figuring this out in mggraph. I have tried for a few hours now and I am not sure if this even possible with mggraph. Whenever I try to build a script using Restore-MgDirectoryDeletedUser/Item which google, copilote etc tells me to use I only get this error: The term 'Restore-MgDirectoryDeletedUser/item' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. Or I get that it "works" but that the proxy/domain conflicts: Errors detected while trying to restore the user restoreUserErrors: ErrorValue:<pii><pii>E*****.E*******</pii>@domain.com</pii> ObjectType: ConflictingObjectId:, ErrorType:UserPrincipalName, ErrorId:InvalidDomainErrorValue:<pii>smtp:<pii>ee</pii>@domain.com</pii> ObjectType: ConflictingObjectId:, ErrorType:ProxyAddress, ErrorId:InvalidDomain Status: 400 (BadRequest) ErrorCode: Request_BadRequest Date: 2025-09-08T13:49:36 Since I do not have the first domain in the source tenant anymore I need to restore the user to a different domain. Does anyone have any idea on how I can recreate the msol version to mggraph? I feel like I have tried everything to my knowledge now so hopefully anyone here can give me help or tips. Thanks! /Adam135Views0likes5CommentsWhere can I find a lots of scripts like Script Guy site used to have?
Hi, I am sorry if this is a bit of easy post but the internet appears to be so spread out these days and de-centralised from what it used to be. I am looking for a site that has lots of good scripts similar to the good old Script Guy site. Please can you help. Thanks2.5KViews2likes3CommentsWhy does this return a .csv with the length of the group names?
Hi, I've been trying to list the names of the Entra groups a user is a member of. Most of the scripts I've found online will only display the group ID and leaves the other fields blank, if they show up at all. I found this command works in the terminal: Get-MgUserMemberOf -UserId $userPrincipalName | % {($_.AdditionalProperties).displayName} However, when I try to export it to CSV is get a single column named "Length" and a number in each row which I believe corresponds to the lenght of the group name in characters. Here's the full command: Get-MgUserMemberOf -UserId $userPrincipalName | % {($_.AdditionalProperties).displayName} | Export-Csv -Path "C:\Temp\GroupMemberships.csv" -NoTypeInformation What am I doing wrong?45Views0likes2CommentsUnleashing Parallelism in PowerShell
This blog on my site got a lot of possitive feedback. Hopefully it can help others as well hence I share it here. If you want to check more check my blog on: https://bartpasmans.tech/ or check my LinkedIn: https://www.linkedin.com/in/bart-pasmans-6533094b/ Unleashing Parallelism in PowerShell If you’ve been around PowerShell for a while, you know it’s great at looping through stuff. Need to process a list of files? Easy. Query a set of servers? Piece of cake. But sometimes… you hit a wall. The problem? Sequential execution. By default, your loops work in a single-file line, like shoppers at a small-town bakery. That’s fine for five people. Not so fine for five thousand. That’s where ForEach-Object -Parallel enters the chat. 🚀 This feature, introduced in PowerShell 7, lets you process multiple items at the same time, tapping into all those CPU cores just sitting there looking bored. Today, we’re going to walk through how it works, why it’s a game-changer, and where you should (and shouldn’t) use it. We’ll keep it hands-on, so keep PowerShell open! you’ll see the 🎬 icon whenever it’s time to get your hands dirty. Today’s Toolbelt Here’s the deal: ForEach-Object -Parallel is like the express checkout lane at the grocery store. Instead of every task waiting for the one ahead to finish, they all get their own lane. We’ll explore: Basic parallel loops – Using ForEach-Object -Parallel in the simplest form Passing variables – How to get data into your parallel script block Controlling thread counts – Because unlimited parallelism can get… messy Real-world scenarios – Places where it shines (and where it doesn’t) Why Parallel? Imagine you have 50 servers to check for a certain log file. Running them one after another takes… forever. With parallel processing, you can hit multiple servers at once, finishing in a fraction of the time. 📒 Under the hood: PowerShell spins up runspaces, lightweight, isolated environment, to execute each chunk of work simultaneously. It’s not “true” OS-level multithreading, but it’s incredibly efficient for I/O-bound tasks like network calls, file reads, or API requests. 1..5 | ForEach-Object -Parallel { Start-Sleep -Seconds 1 "Task $_ completed on thread $([System.Threading.Thread]::CurrentThread.ManagedThreadId)" } What’s happening: 1..5 gives us five items. Each item is processed in a parallel runspace. They all sleep for one second…. 🥁🥁🥁 but because they run in parallel, the whole thing finishes in just over a second, not five! My previous blog: https://bartpasmans.tech/start-scripting-like-a-pro-6-speeding-up-your-code/ I showed you how to make your own threads and consume them. Check it out! 😊 This blog sticks with PowerShell cmdlets natively. Passing Data Into Parallel Blocks One catch with ForEach-Object -Parallel: it runs in its own scope. Your outer variables aren’t magically available inside. 🎬 Here’s how to pass variables in: $prefix = "Server" 1..3 | ForEach-Object -Parallel { "$using:prefix-$($_)" } 📒 The magic word: $using: tells PowerShell to bring in a variable from outside the parallel block. Controlling the Chaos Yes, parallelism is powerful, but if you let 200 jobs spin up at once, you might as well be starting a tiny CPU apocalypse 💣. 🎬 Throttle it with 1..10 | ForEach-Object -Parallel { Start-Sleep -Seconds 2 "Processed $_" } -ThrottleLimit 3 Here, only three parallel tasks run at a time. As soon as one finishes, the next starts. Real-World Example: Network Ping 🎬 Checking multiple hosts in parallel: $servers = "server1","server2","server3","server4","server5" $servers | ForEach-Object -Parallel { $result = Test-Connection -ComputerName $_ -Count 1 -Quiet "$_ is " + ($(if ($result) { "online" } else { "offline" })) } -ThrottleLimit 2 The pings happen two at a time. Overall time drops drastically compared to running sequentially. When Not to Use It 📒 Parallelism is not a free lunch. If your task is super short and light (like adding numbers), spinning up runspaces is actually slower. For CPU-heavy operations, you might saturate your system quickly. Avoid it when order matters—parallel execution doesn’t guarantee output order unless you take extra steps. Summary Wrapping It Up! PowerShell Meets Parallelism 🎉 Today we saw how ForEach-Object -Parallel lets you take PowerShell’s already-great iteration abilities and put them into warp speed. We covered: The basics of parallel loops Passing variables with $using: Throttling to keep your system happy Real-world use cases like pinging servers The takeaway? When you’re faced with a big list of time-consuming tasks, don’t just wait your turn in the single checkout lane. Open more lanes with ForEach-Object -Parallel! Just remember that more isn’t always better. Got your own clever use for parallel loops? Share it, I love seeing how people bend PowerShell to their will. Until next time! Keep automating, keep experimenting, and keep pushing your scripts to the next level. 🚀☕🍰17Views0likes0CommentsError setting profile for interface Primary LAN Interface
Hi all I have a problem with this script. It says "Error setting profile for interface Primary LAN Interface: The network connection profile is corrupted". I need to set the Network card Protected EAP Properties to "Smartcard or other certificate" and set the Trusted Root Certification Autorities to use our Root certificate. Is there any other way to automate this or can you help me finding the problem in this script? Thanks for your help! Powershell Script: # ================================ # 802.1X PEAP (EAP-TLS) for Wired # Interface: "Primary LAN Interface" # Root CA can be selected by Thumbprint or Subject Match # Run as Administrator # ================================ $InterfaceName = "Primary LAN Interface" # Target NIC display name $ProfileName = "Network" # Wired profile name to manage $TempFolder = "D:\iltis\tools\Temp\LanProfile" # Root CA selection (choose ONE approach) $RootCAThumbprint = "96f2bf58b39db8b704a4dda8c5df456c725fce24" # e.g. "AB12CD34EF56..."; leave blank to use subject search $RootCASubjectLike = "Root" # Used only if $RootCAThumbprint is blank # ---------- Helpers ---------- function Ensure-Folder($path) { if (-not (Test-Path $path)) { New-Item -ItemType Directory -Path $path | Out-Null } } function Get-RootCAThumbprint { param( [string]$Thumbprint, [string]$SubjectLike ) if ($Thumbprint -and $Thumbprint.Trim() -ne "") { return ($Thumbprint -replace "\s","").ToUpper() } $match = Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Subject -like "*$SubjectLike*" } | Select-Object -First 1 if (-not $match) { throw "Root CA with subject like '$SubjectLike' not found in LocalMachine\Root." } return ($match.Thumbprint -replace "\s","").ToUpper() } function Start-WiredAutoConfig { $svc = Get-Service -Name dot3svc -ErrorAction SilentlyContinue if (-not $svc) { throw "Wired AutoConfig (dot3svc) service not found." } if ($svc.StartType -ne 'Automatic') { Set-Service dot3svc -StartupType Automatic } if ($svc.Status -ne 'Running') { Start-Service dot3svc } } function Get-NicOrThrow { param([string]$Name) $nic = Get-NetAdapter -Name $Name -ErrorAction SilentlyContinue if (-not $nic) { throw "Network adapter '$Name' not found. Use Get-NetAdapter to confirm the exact name." } if ($nic.Status -ne 'Up') { Write-Warning "Adapter '$Name' is not Up (status: $($nic.Status)). Continuing anyway." } return $nic } # Minimal valid LAN profile XML with EAPHostConfig placeholder (we’ll inject the Root CA thumbprint). function New-LanProfileXml { param([string]$ProfName) @" <?xml version="1.0"?> <LANProfile xmlns="http://www.microsoft.com/networking/LAN/profile/v1"> <name>$ProfName</name> <MSM> <security> <OneX xmlns="http://www.microsoft.com/networking/OneX/v1"> <authMode>userOrComputer</authMode> <EAPConfig> <EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig"> <EapMethod> <Type xmlns="http://www.microsoft.com/provisioning/EapCommon">25</Type> <AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId> </EapMethod> <Config xmlns="http://www.microsoft.com/provisioning/EapHostConfig"> <Eap xmlns="http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1"> <Type>13</Type> <EapType xmlns="http://www.microsoft.com/provisioning/EapTlsConnectionPropertiesV1"> <CredentialsSource> <CertificateStore> <SimpleCertSelection>true</SimpleCertSelection> </CertificateStore> </CredentialsSource> <ServerValidation> <DisableUserPromptForServerValidation>true</DisableUserPromptForServerValidation> <ServerNames></ServerNames> <TrustedRootCA>__ROOT_CA_THUMBPRINT__</TrustedRootCA> </ServerValidation> <DifferentUsername>false</DifferentUsername> </EapType> </Eap> </Config> </EapHostConfig> </EAPConfig> </OneX> </security> </MSM> </LANProfile> "@ } # ---------- Main ---------- try { Write-Host "Preparing environment..." -ForegroundColor Cyan Ensure-Folder $TempFolder Start-WiredAutoConfig $null = Get-NicOrThrow -Name $InterfaceName $thumb = Get-RootCAThumbprint -Thumbprint $RootCAThumbprint -SubjectLike $RootCASubjectLike Write-Host "Using Root CA Thumbprint: $thumb" -ForegroundColor Green # Try to export existing profile for this interface+name; if missing, build a fresh one. $exported = $false Write-Host "Exporting existing wired profile (if present)..." -ForegroundColor Cyan $null = netsh lan export profile folder="$TempFolder" interface="$InterfaceName" name="$ProfileName" 2>$null $ProfilePath = Join-Path $TempFolder "$ProfileName.xml" if (Test-Path $ProfilePath) { $exported = $true } if (-not $exported) { Write-Host "No existing profile named '$ProfileName' found. Creating a new one..." -ForegroundColor Yellow $xmlText = New-LanProfileXml -ProfName $ProfileName $xmlText = $xmlText -replace "__ROOT_CA_THUMBPRINT__", $thumb $xmlText | Set-Content -Path $ProfilePath -Encoding UTF8 } else { # Load existing, replace EAP host config with our desired PEAP->EAP-TLS block [xml]$xml = Get-Content $ProfilePath # Find any EapHostConfig node and replace its InnerXml with our config (PEAP 25 -> inner EAP-TLS 13) $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) $ns.AddNamespace("lp", "http://www.microsoft.com/networking/LAN/profile/v1") $ns.AddNamespace("ox", "http://www.microsoft.com/networking/OneX/v1") $eapConfigNode = $xml.SelectSingleNode("//lp:LANProfile/lp:MSM/lp:security/ox:OneX/ox:EAPConfig", $ns) if (-not $eapConfigNode) { throw "EAPConfig node not found in exported profile. Cannot proceed safely." } $newEap = New-LanProfileXml -ProfName $ProfileName # extract just the EAPHostConfig from the template [xml]$tmp = $newEap $tmpNs = New-Object System.Xml.XmlNamespaceManager($tmp.NameTable) $tmpNs.AddNamespace("lp", "http://www.microsoft.com/networking/LAN/profile/v1") $tmpNs.AddNamespace("ox", "http://www.microsoft.com/networking/OneX/v1") $eapHostConfig = $tmp.SelectSingleNode("//lp:LANProfile/lp:MSM/lp:security/ox:OneX/ox:EAPConfig/*", $tmpNs) # Replace placeholder with real thumbprint $eapHostConfigOuterXml = $eapHostConfig.OuterXml.Replace("__ROOT_CA_THUMBPRINT__", $thumb) # Replace EAPConfig contents $eapConfigNode.InnerXml = $eapHostConfigOuterXml # Save back $xml.Save($ProfilePath) } Write-Host "Importing wired 802.1X profile to '$InterfaceName'..." -ForegroundColor Cyan # Adds the profile and associates it with the specified interface netsh lan add profile filename="$ProfilePath" interface="$InterfaceName" # Optional: force 802.1X reauth/reconnect try { netsh lan reconnect interface="$InterfaceName" | Out-Null } catch {} Write-Host "" Write-Host "✅ Done." -ForegroundColor Green Write-Host "The adapter '$InterfaceName' is configured for PEAP with inner 'Smart Card or other certificate' (EAP-TLS) and trusts the specified Root CA." -ForegroundColor Green Write-Host "Profile name: $ProfileName" Write-Host "" Write-Host "Tip: If your NAC expects machine auth, make sure a valid machine certificate is present in LocalMachine\My." -ForegroundColor DarkGray } catch { Write-Error $_.Exception.Message exit 1 }86Views0likes2CommentsCopy text always as text from Onenote
Hi there, I have the following problem: I often copy paste things from here to there which is never is any problem. Except I am copying from Onenote. Because then in most of the cases it just spits out an image of the text I copied instead of the text itself. ctrl+ shift + v often works, but not always and also it is quite annoying to remember everytime to hit shift as well, when pasting from Onenote. The only real solution I found so far was an auto hotkey script. But as I am working with this on my business PC I'd like to have a non thirdparty solution. So I thought there might be a solution to this using powershell, where it checks, if I copy text from Onenote and if so, remove formatting automatically, so I can paste it as text right away with ctrl+v Anyone came across this issue and might have a working solution already as I am not familiar with powershell unfortunately? Best regards!Solved79Views0likes1CommentBug: Invoke-MgGraphRequest not respecting ErrorAction.
Hi folks, This is a brief callout that Invoke-MgGraphRequest is not currently respecting the ErrorAction parameter. Rather, it's hardwired to throwing an exception as if ErrorAction:Stop had been provided. If you're like me and typically use ErrorAction:Stop in a try/catch block then you won't be impacted, but if use another value like Continue (the default) or SilentlyContinue, you may find this breaks your automation. Example Hopefully this is addressed in a future version of the Microsoft.Graph.Authentication module. Cheers, Lain34Views0likes0CommentsFetch Email of Login User In System Context
Dear Team, We are working on retrieving email address of the user joined to Entra ID from Entra-joined Windows devices, specifically while running in a system context.The whoami /upn command successfully returns the joined user’s email address in a user context, but it does not work in a system context, particularly when using an elevated terminal via the psexec utility.We also tested the dsregcmd /status command; however, in a system context, the User Identity tab in the SSO State section only appears when there is an error in AzureAdPrt. Under normal, healthy operating conditions, this command does not provide the user identity or the full domain username. We would greatly appreciate guidance on how to retrieve the Entra ID joined user’s email address in a system context, especially from those with prior experience in this area. Thank you for your support.Solved152Views0likes3CommentsProblem with Copy-Item
I'm trying to copy all files from a webdav folder to a local folder. It worked one time, after that, just a file with the the expected folder name (back) was created. What could be the issue? # Define Drive $netzLaufwerk = "Z:" # Connect net use $netzLaufwerk $webdavUrl /user:$username $passwort # Copy files Copy-Item -Path "$netzLaufwerk\*" -Destination "C:\Users\innov\Desktop\Backup\back" -Recurse # Disconnect net use $netzLaufwerk /delete61Views0likes1Comment