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 03, 2026Copper Contributor46Views0likes3Comments"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 24, 2026Copper Contributor47Views0likes2Comments**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 Contributor20Views0likes0CommentsGet-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 15, 2026Tin Contributor177Views0likes5CommentsAccept 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 08, 2026Tin Contributor71Views0likes3CommentsEdit Windows Shortcut properties TargetPath and WorkingDirectory with a script?
I've moved data to a new drive, and there are a lot of shortcuts (*.lnk files) to different files in the data set. I'd like to create a script that edits the file paths in the shortcut properties "TargetPath" and WorkingDirectory" so that these paths are accurate based on where the files are now located. Only parts of the file paths must change, and the file names must not be changed. For example, if the old path and filename are "D:\Dataset\Folder1\Folder2\filenameX.doc" the new path should be "E:\Folder1\Folder2\filenameX.doc" - where the drive letter is changed from D to E and the folder "Dataset" is removed from the path. The following script was created for me by Google search results, but it doesn't alter the values of these named properties at all. If anyone can provide edits that cause the script to work, I'd appreciate it very much. Thanks! # Define the paths and folder to search $searchFolder = "E:\Internet Files\Shortcut Ops temp" $oldPath = "D:\Dataset\" $newPath = "E:\" # Create the COM object for shell operations $shell = New-Object -ComObject WScript.Shell # Get all .lnk files in the search folder (including subfolders) $shortcuts = Get-ChildItem -Path $searchFolder -Filter *.lnk -Recurse foreach ($file in $shortcuts) { # Open the existing shortcut $lnk = $shell.CreateShortcut($file.FullName) # Check if the TargetPath contains the old path string if ($lnk.TargetPath -like "*$oldPath*") { # Update TargetPath and WorkingDirectory by replacing the old string $lnk.TargetPath = $lnk.TargetPath.Replace($oldPath, $newPath) $lnk.WorkingDirectory = $lnk.WorkingDirectory.Replace($oldPath, $newPath) # Save the changes to the existing file $lnk.Save() Write-Host "Updated: $($file.Name)" -ForegroundColor Cyan } }jamesmcxMay 02, 2026Copper Contributor257Views0likes2CommentsPowerShell 7.x ISE-style app — would anyone be interested in testing or reviewing the source?
Hi everyone, My name is Ron, and I have been working on a Windows desktop app called PowerShellStudio. It is intended to be a modern PowerShell 7.x ISE-style scripting environment for Windows. The app is written in .NET 10 using Visual Studio 2026. I am not trying to replace VS Code. The idea is closer to the original Windows PowerShell ISE: a focused editor, integrated PowerShell console, script execution, syntax diagnostics, command and parameter completion, metadata-based IntelliSense, and a simpler workflow for people who liked the old ISE experience. The app is running and usable, but it is still under active development. Before I go further, I wanted to see whether there is any community interest. I am preparing a final preview version to add to GitHub. If people are interested, I will upload the complete source code so anyone can examine it, build it, and run it themselves. Since this is a scripting tool that can run local PowerShell code, I want to make the project as transparent as possible. I would especially appreciate feedback on: Whether this kind of app would be useful to anyone How the editor and console should behave compared with the legacy ISE What features would be expected before it feels useful Any concerns about the approach Whether anyone would be willing to test or review the code I am not presenting it as finished or perfect. I am looking for honest feedback while I am still actively working on it. Thanks, RonNJDevils28Apr 26, 2026Copper Contributor161Views1like2CommentsPowershell 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. Thanks112Views0likes2CommentsPowerShell 7 PnP.PowerShell Header Issue
I am trying to connect to the PnPOnline module using PS7. I am running PowerShell version 7.6.0 (Core), PnP.PowerShell PSEdition Core, and have my PnP PowerShell App registered in Azure I have my top level site as the $siteURL variable, my ClientID number as the $clientID variable and the ClientSecret value as the $clientSecret variable... When using the command Connect-PnPOnline -Url $siteUrl -ClientId $clientId -ClientSecret $clientSecret the following is returned: WARNING: Connecting with Client Secret uses legacy authentication and provides limited functionality. We can for instance not execute requests towards the Microsoft Graph, which limits cmdlets related to Microsoft Teams, Microsoft Planner, Microsoft Flow and Microsoft 365 Groups. You can hide this warning by using Connect-PnPOnline [your parameters] -WarningAction Ignore Connect-PnPOnline: The given header was not found. I have double checked my variables, and all components and still receiving this error. I know there is a certificate method for the App Registration, but what else need to happen to make my connection successful? Or should I go the certificate route for the App Registration?SolvedtleannaMar 31, 2026Copper Contributor188Views0likes2Comments
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