Forum Widgets
Latest Discussions
[Bug] ExchangeOnlineManagement uses incorrect TenantId in requests
An interaction between the ExchangeOnlineManagement powershell module and Microsoft.Identity.Client 4.83.0+ results in the REST API requests sent by the ExchangeOnlineManagement powershell module using realm.onmicrosoft.com in place of the expected Guid TenantId. This results in the dreaded Expired or Invalid pagination request after fetching one page. As discussed in https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/6093, Microsoft.Identity.Client.AuthenticationResult.TenantId can no longer be trusted to contain either null or the expected Guid TenantId, but instead will generally contain the realm.onmicrosoft.com realm name as of Microsoft.Identity.Client 4.83.0 As version 3.10.0 of the ExchangeOnlineManagement powershell module now depends on Microsoft.Identity.Client 4.83.1, this version of the powershell module can no longer retrieve groups with more than 1000 members or enumerate the groups, contacts, recipients, etc. in a domain that has more than 1000 of each without running into the dreaded Expired or Invalid pagination request. In theory the following Lib.Harmony patch encodes a potential fix for this issue (tested locally using ExchangeOnlineFetch 3.10.0 in a dotnet 10 program): using System.Reflection.Emit; using HarmonyLib; [HarmonyPatch("Microsoft.Exchange.Management.AdminApiProvider.Authentication.TokenProviderUtils", "GetTokenInformation")] static class Patch_TokenProviderUtils_GetTokenInformation { private static Harmony? _harmony = null; public static void PatchOnce() { var asms = AppDomain.CurrentDomain.GetAssemblies(); if (_harmony is null && asms.FirstOrDefault(e => e.GetName().Name == "Microsoft.Exchange.Management.AdminApiProvider") is { } asm && asm.GetType("Microsoft.Exchange.Management.AdminApiProvider.Authentication.TokenProviderUtils") is { } type && type.GetMethod("GetTokenInformation") is { } method) { var harmony = new Harmony("com.github.klightspeed.exchangeonlinemanagement.tenantidfix"); harmony.Patch( method, transpiler: new HarmonyMethod(typeof(Patch_TokenProviderUtils_GetTokenInformation), nameof(Transpiler)) ); _harmony = harmony; } } static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { var matcher = new CodeMatcher(instructions); var get_TenantId = AccessTools.PropertyGetter("Microsoft.Identity.Client.AuthenticationResult:TenantId"); var get_Organization = AccessTools.PropertyGetter("Microsoft.Exchange.Management.AdminApiProvider.Authentication.TokenProviderContext:Organization"); // patch the following code snippet: // // if (IsCertificateBasedConnection(context)) // { // var upn = GetUPNForAppOnlyBasedConnection(context); // var tenantId = JwtSecurityTokenUtils.GetTenantId(tokenAcquisitionResult.AccessToken); // return TokenInformation.Create( // upn, // authorizationHeader, // tokenAcquisitionResult.TenantId ?? tenantId ?? context.Organization, // tokenAcquisitionResult.ExpiresOn // ); // } // // to // // if (IsCertificateBasedConnection(context)) // { // var upn = GetUPNForAppOnlyBasedConnection(context); // var tenantId = JwtSecurityTokenUtils.GetTenantId(tokenAcquisitionResult.AccessToken); // return TokenInformation.Create( // upn, // authorizationHeader, // PatchedTenantId(tokenAcquisitionResult.TenantId, context) ?? tenantId ?? context.Organization, // tokenAcquisitionResult.ExpiresOn // ); // } matcher.MatchStartForward( new CodeMatch(CodeInstruction.LoadArgument(0)), CodeMatch.Calls(get_TenantId), new CodeMatch(OpCodes.Dup), new CodeMatch(OpCodes.Brtrue_S), new CodeMatch(OpCodes.Pop) ); if (matcher.IsValid) { matcher.Advance(2); matcher.Insert( CodeInstruction.LoadArgument(1), new CodeInstruction(OpCodes.Call, get_Organization), CodeInstruction.Call(() => PatchedTenantId(default, default!)) ); } return matcher.InstructionEnumeration(); } static string? PatchedTenantId(string? tenantId, string? organization) => tenantId == organization ? null : tenantId; }klightspeedJul 10, 2026Copper Contributor44Views0likes3CommentsGet-ChildItem | Write-Host
The command in the title lists all the short names of files and folders in the current folder, whereas `Get-ChildItem * | Write-Host` lists the full names (including paths). I compared the output of `Get-ChildItem | gm` with the output of `Get-ChildItem * | gm`: no difference. If the very same objects are piped into Write-Host, how can the cmdlet give consistently different outputs?BosjabouterJun 30, 2026Tin Contributor167Views0likes5Comments"VBAF Learning Trail -- From Zero to AI Developer in PowerShell 5.1"
VBAF -- Getting Started A Guided Trail from Zero to AI Developer Welcome. You are about to learn how artificial intelligence actually works -- not by reading about it, but by running it, watching it, and breaking it. VBAF implements neural networks, reinforcement learning and multi-agent systems from scratch in PowerShell 5.1. Every algorithm is readable. Every concept is explained in the code comments. This guide takes you from installation to building your own AI agent. Follow the camps in order. Do not skip ahead. Time required: 2-4 hours for Camps 0-3. Camps 4-5 are open-ended. CAMP 0 -- BASECAMP Get VBAF installed and your first output on screen Goal: see "VBAF Framework ready!" on your screen Step -- Install VBAF from PSGalleryJupyterPSJun 25, 2026Copper Contributor44Views0likes2Comments**Title:** VBAF -- educational AI and reinforcement learning framework in pure PS 5.1
Hello, I have been building an educational framework for learning AI concepts in PowerShell 5.1 and wanted to share it with this community. VBAF (Visual AI & Reinforcement Learning Framework) implements neural networks, Q-learning, DQN, PPO and A3C from scratch -- no Python, no external dependencies, no cloud services. The goal is to make AI concepts accessible to PowerShell developers. Every algorithm has full comments explaining the mathematics in plain English, with references to the original research papers. Quick start: ```powershell Install-Module VBAF -Scope CurrentUser . .\VBAF.LoadAll.ps1 # See a neural network learn XOR & .\VBAF.Core.Example-XOR.ps1 # Train a DQN agent on CartPole $agent = (Invoke-DQNTraining -Episodes 50 -FastMode)[-1] $agent.PrintStats() ``` The framework also includes a multi-agent market simulation where four company agents compete using Q-learning -- price wars, innovation races and tacit collusion emerge naturally without being programmed. For teachers: docs/teaching/ contains a 4-week course outline, lab exercises and exam questions. GitHub: https://github.com/JupyterPS/VBAF PSGallery: https://www.powershellgallery.com/packages/VBAF Happy to answer any questions about the implementation choices or the PS 5.1 class system quirks. Henning -- Roskilde, DenmarkJupyterPSJun 22, 2026Copper Contributor20Views0likes0CommentsAccept pipeline input?
The off-line help files of all parameters of all cmdlets have the answer False to the question in the title. This is confusing and wrong. And since I'm at it: the 3rd and 4th syntax item of the off-line help file of Get-Help miss the parameters -Examples, -Parameters, respectively (compared to the syntax items of the on-line help). I'm a learner of PowerShell and find it tiresome that the off-line help is unreliable and that I have to go to the online help so often. I use Windows PowerShell version 5.1.26100.8457BosjabouterJun 10, 2026Tin Contributor69Views0likes3CommentsPowershell Entra and General Forum Layout Questions
Hello, I am returning to PowerShell, and it seems a lot has changed. I need to create some Security Groups in MS Entra and would like to know the best way to do so. I have a .csv file for the groups. Also, what is the best way to display the topic titles as a list in this forum? At this moment, I have to go scroll through pages of posts, and it's not easy. I used to like the old formats that let you see all the thread titles. Thanks111Views0likes2CommentsError PowerShell 300-1015 (80)
Hello, using P.Shell for office installation, with ODT, it gives me the following error shown in the photo, or opening the console in any folder with the right mouse button "open the P.S. window here" gives an error: Missing termination character in the string: ". + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString While if I run the command on the desktop, the window opens normally! ThanksAlpha45Jun 05, 2026Brass Contributor169Views0likes1CommentError PowerShell 30015-1015 (80)
Hello, using PowerShell for office installation, with ODT, it gives me the following error shown in the photo, or opening the console in any folder with the right mouse button "open the P.S. window here" gives an error: Missing termination character in the string: ". + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString Or Set-Location : Impossibile trovare un parametro posizionale che accetta l'argomento 'Ripristino\Office\Office'. In riga:1 car:1 + Set-Location -literalPath D:\Ripristino\File Ripristino\Office\Office ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Set-Location], ParameterBindingException + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.SetLocationCommand While if I run the command on the desktop, the window opens normally! ThanksAlpha45Jun 05, 2026Brass Contributor141Views0likes1CommentGui to deploy folder contents to multiple VMs
I am trying to improve imaging computers where I work. I need to create a gui for new hires since the imaging process is so complicated. I need the GUI to request necessary computer names that are being imaged and then copy files from a local workstation to the machines that are being imaged on the network that our technicians do not have physical access to. I have turned to Powershell for the solution in an attempt to improve on my knowledge which is basic really. Below is the code I have come up with so far. In this code I am getting the location of the file. I would rather copy the entire folder instead of the file but I couldnt find the code to do that. So, if that is possible please show me how. If not I figure I would have to save these imaging files to a ZIP file. Then I could maybe use this GUI I am working on to move the zip file to the remote computers. Add-Type -AssemblyName System.Windows.Forms # Create the form $form = New-Object System.Windows.Forms.Form $form.Text = "File and Network Location Collector" $form.Size = New-Object System.Drawing.Size(400, 200) # Create the label for file name $fileLabel = New-Object System.Windows.Forms.Label $fileLabel.Text = "File Name:" $fileLabel.Location = New-Object System.Drawing.Point(10, 20) $form.Controls.Add($fileLabel) # Create the text box for file name $fileTextBox = New-Object System.Windows.Forms.TextBox $fileTextBox.Location = New-Object System.Drawing.Point(100, 20) $fileTextBox.Size = New-Object System.Drawing.Size(250, 20) $form.Controls.Add($fileTextBox) # Create the label for network location $networkLabel = New-Object System.Windows.Forms.Label $networkLabel.Text = "Network Location:" $networkLabel.Location = New-Object System.Drawing.Point(10, 60) $form.Controls.Add($networkLabel) # Create the text box for network location $networkTextBox = New-Object System.Windows.Forms.TextBox $networkTextBox.Location = New-Object System.Drawing.Point(100, 60) $networkTextBox.Size = New-Object System.Drawing.Size(250, 20) $form.Controls.Add($networkTextBox) # Create the button to submit $submitButton = New-Object System.Windows.Forms.Button $submitButton.Text = "Submit" $submitButton.Location = New-Object System.Drawing.Point(150, 100) $form.Controls.Add($submitButton) # Add event handler for the button click $submitButton.Add_Click({ $fileName = $fileTextBox.Text $networkLocation = $networkTextBox.Text [System.Windows.Forms.MessageBox]::Show("File Name: $fileName`nNetwork Location: $networkLocation") }) # Show the form $form.ShowDialog() In this portion of the code it is copying from one source to many locations. Thank you for any assistance as this would help my organization a lot. We are getting several new hires who are very new to the industry. This would be a huge blessing. Pardon the change in font size. It did that for no reason, its my first time using the blog, and there appears to be no way to change the sizes lol. Forgive me. #Define the source folder and the list of target computers $sourceFolder = "C:\Path\To\SourceFolder" $destinationFolder = "C:\Path\To\DestinationFolder" $computers = @("Computer1", "Computer2", "Computer3") # Replace with actual computer names # Function to copy the folder function Copy-Folder { param ( [string]$source, [string]$destination ) Copy-Item -Path $source -Destination $destination -Recurse -Force } # Execute the copy operation on each computer foreach ($computer in $computers) { Invoke-Command -ComputerName $computer -ScriptBlock { param ($source, $destination) Copy-Folder -source $source -destination $destination } -ArgumentList $sourceFolder, $destinationFolder } Write-Host "Folder copied to all specified computers."techhondoJun 05, 2026Copper Contributor142Views0likes1Comment
Tags
- Windows PowerShell1,211 Topics
- PowerShell349 Topics
- office 365281 Topics
- azure active directory146 Topics
- sharepoint133 Topics
- windows server132 Topics
- azure101 Topics
- exchange100 Topics
- community58 Topics
- azure automation50 Topics