Forum Widgets
Latest Discussions
Bug: 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, LainLainRobertsonOct 23, 2025Silver Contributor57Views0likes2CommentsLaunch program remotely which must remain running
Hello everyone, I have to start and leave programs running on some remote PCs, I used invoke-command with start-job and start-process. Launching the script from my powershell window, the executables remain running until I close the window itself, I believe for reasons of remote sessions started. So if I schedule the start of this script in the Windows "Task Scheduler", the session is opened and closed and the executables start and close shortly after, that is, when the scheduled task completes. I also set the "-noexit" argument, but nothing happened. What can I do so that I can schedule these startups and let the affected programs run? I hope I was clear, ask if you need it, thanks everyone.Mariolino118Oct 22, 2025Copper Contributor94Views0likes3CommentsMap vmdk to guest volume
I have a Hyper-V cluster and want PowerShell to give me a list of what vmdk file is assigned to which volume mount point in the virtual machine OS (Windows). Example: vmdk file mount point ------------------------------------------------------------------------------------------- C:\ClusterStorage\Data1\VM\ComputerA\Virtual Hard Disks\OSDisk.vhdx C:\ C:\ClusterStorage\Data1\VM\ComputerA\Virtual Hard Disks\MainMount.vhdx M:\ C:\ClusterStorage\Data1\VM\ComputerA\Virtual Hard Disks\Temp.vhdx M:\Temp The vmdks for C: and M: are mapped to drives in the guest, whereas Temp.vhdx is mounted in a folder under M:\. The main challenge for me is actually to find the correct elements that allow me to link a VMDK to a disk inside the virtual machine OS. The ones I found so far are: Get-Disk gives me numbers for adapter, port, target, and LUN, and Get-VMHardDiskDrive returns numbers for controller and location, which I guess link to target and LUN. But I'm pretty unsure whether it's safe to use these properties... Get-Disk returns a path, and I think I can use this to map the result of a win32_mountpoint CIM query to it to get the volume mount point... Does anyone have some valuable information for me on this?ahinterlOct 20, 2025Brass Contributor16Views0likes0CommentsNew-MgBookingBusinessService | Customer Information Questions
I'm trying to turn off the stock Customer Information questions except for the customer email using PowerShell and New-MgBookingBusinessService and cannot seem to figure it out. Any assistance is much appreciated! # Prompt for Booking Business ID $bookingBusinessId = Read-Host "Enter the Booking Business ID (e.g., email address removed for privacy reasons)" # Prompt for default duration in minutes $defaultDurationMinutes = Read-Host "Enter default appointment duration in minutes (e.g., 15)" $defaultDuration = [TimeSpan]::FromMinutes([double]$defaultDurationMinutes) # Post-buffer stays at 5 minutes $postBuffer = [TimeSpan]::FromMinutes(5) # Hardcoded Excel file path $excelFilePath = "C:\Users\apettit\OneDrive - Eau Claire Area School District\Downloads\adamtestconferencedata.xlsx" # Prompt for worksheet/tab name $sheetName = Read-Host "Enter the worksheet/tab name to read data from" # Import Excel data using Import-Excel (requires ImportExcel module) if (-not (Get-Module -ListAvailable -Name ImportExcel)) { Install-Module -Name ImportExcel -Scope CurrentUser -Force } Import-Module ImportExcel $staffEmails = Import-Excel -Path $excelFilePath -WorksheetName $sheetName # Retrieve all staff members for the booking business Write-Host "Fetching all staff members for booking business ID: $bookingBusinessId" $allStaff = Get-MgBookingBusinessStaffMember -BookingBusinessId $bookingBusinessId if (-not $allStaff) { Write-Error "No staff members found for the booking business ID: $bookingBusinessId" return } # Retrieve all custom questions Write-Host "Fetching all custom questions for booking business ID: $bookingBusinessId" $allCustomQuestions = Get-MgBookingBusinessCustomQuestion -BookingBusinessId $bookingBusinessId if (-not $allCustomQuestions) { Write-Error "No custom questions found for the booking business ID: $bookingBusinessId" return } # Loop through each staff member from Excel automatically Write-Host "Creating individual booking services for each staff member..." foreach ($row in $staffEmails) { $email = $row.emailAddress.Trim().ToLower() # Automatically match staff from Booking Business $matchingStaff = $allStaff | Where-Object { $_.AdditionalProperties["emailAddress"] -and ($_.AdditionalProperties["emailAddress"].Trim().ToLower() -eq $email) } if ($matchingStaff) { $staffId = $matchingStaff.Id $displayName = $matchingStaff.AdditionalProperties["displayName"] Write-Host "Automatically creating service for: ${displayName} ($email)" -ForegroundColor Cyan try { # Prepare custom questions $customQuestions = $allCustomQuestions | ForEach-Object -Begin { $isLast = $false } -Process { $isLast = ($_.Id -eq $allCustomQuestions[-1].Id) $questionAssignment = New-Object Microsoft.Graph.PowerShell.Models.MicrosoftGraphBookingQuestionAssignment $questionAssignment.QuestionId = $_.Id $questionAssignment.IsRequired = if ($isLast) { $false } else { $true } $questionAssignment } # Prepare the reminder $defaultReminder = New-Object Microsoft.Graph.PowerShell.Models.MicrosoftGraphBookingReminder $defaultReminder.Message = "Don't forget! Family Teacher Conferences are tomorrow, and we are excited to visit with you! If you wish to change the meeting type (virtual, in-person, hybrid, or phone), please let the teacher know as soon as possible!" $defaultReminder.Offset = [TimeSpan]::FromDays(1) $defaultReminder.Recipients = @("customer") # Prepare service parameters $serviceParams = @{ BookingBusinessId = $bookingBusinessId DisplayName = "${displayName} Family Conference" Description = "Family Teacher Conference with ${displayName}" StaffMemberIds = @($staffId) # Assign specific staff member DefaultDuration = $defaultDuration DefaultPrice = 0.00 DefaultPriceType = "free" CustomQuestions = $customQuestions PostBuffer = $postBuffer IsLocationOnline = $true IsCustomerAllowedToManageBooking = $true DefaultReminder = $defaultReminder AdditionalInformation = @" Please arrive on time for your conferences as we will be sticking to a tight schedule. If you wish to change the meeting type (virtual, in-person, hybrid, or phone), please let the teacher know as soon as possible. If you require a translator, please submit a request at this form: https://forms.office.com/r/XWwBFWP7XD "@ # Appears in the customer confirmation email AdditionalProperties = @{ customerEmail = @{ isRequired = $true } # Only email field remains } } # Log service parameters Write-Host "Service Parameters for ${displayName}:" -ForegroundColor Blue $serviceParams.GetEnumerator() | ForEach-Object { Write-Host "$($_.Key): $($_.Value)" } # Create the booking service New-MgBookingBusinessService @serviceParams Write-Host "Booking service successfully created for ${displayName}!" -ForegroundColor Green } catch { Write-Error "Failed to create booking service for ${displayName}: $_" } } else { Write-Warning "No match found for email: $email" } }AP_TC_ECASDOct 17, 2025Brass Contributor36Views0likes1CommentSet Force a user to change password on next logon via Powershell
I have created a script to try and change the user setting 'force password change at next login'. I wish to do this without having to change their password. I have tried both user authentication (using a global admin account) and application authentication (via Client Secret). When I run the script in either authentication context I get access denied when it comes to updating the user. The script was to read in a csv file and do this but I have simplified a script to the following to show the basic concept of the commands I am trying to run and the authentication process. $secureSecret = ConvertTo-SecureString "xxxxxxxxxxxxxxxxx" -AsPlainText -Force $credential = New-Object PSCredential("xxxxxxxxxxxxxxxxxxxxx", $secureSecret) Connect-MgGraph -TenantId "xxxxxxxxxxxxxxxs" -ClientSecretCredential $credential Get-MgUser -UserId "email address removed for privacy reasons" -Property "userPrincipalName,userType,onPremisesSyncEnabled" Update-MgUser -UserId "email address removed for privacy reasons" -PasswordProfile @{ForceChangePasswordNextSignIn = $true} In the application I have created I have assigned the permissions I believe would be required to support this action (I added Directory.ReadWrite.All, just in case) The read user works fine but I get the error below when trying to update Update-MgUser_UpdateExpanded: Insufficient privileges to complete the operation. Status: 403 (Forbidden) ErrorCode: Authorization_RequestDenied Date: 2025-10-15T13:36:46 I have tried this is two different 365 tenants but both fail with the same error. The tenant is a cloud only with no synchronisation from on-premise. I have tried many iterations but have reached the dead end point. Is it possible to force a password reset via a PowerShell script and if so what am I doing wrong with my permissions? TIASolvedJacqui HurstOct 15, 2025Brass Contributor54Views0likes1CommentStop hardcoding secrets! Now what?!
Yeah, we all know this right “STOP DOING THIS”, “STOP DOING THAT!” Yeah… that’s nice, but now what?! When you are already in the PowerShell field for some time and have created some scripts you might have been running into this topic; ‘How to deal with secrets’. There are of course solutions like KeyVault, SecureString and secret providers with API’s which help you to store the secrets you have in a secure environment. Things like this might look familiar; $password = "P@ssw0rd123!" $apiKey = "sk-1234567890abcdef" $connectionString = "Server=myserver;Database=mydb;User=admin;Password=SuperSecret123;" But what if I told you there’s a better way? A way that’s: Secure by default Cross-platform (Windows, Linux, macOS) Works with multiple backends (local, Azure Key Vault, HashiCorp Vault) Standardized across your entire team Built right into PowerShell 7+ (with some extra module support) That way forward is called ‘PowerShell SecretManagement”! What is SecretManagement? Think of PowerShell SecretManagement as the universal remote control for your secrets. With this remote control you can handle credentials for different systems while you just get one unified interface. It doesn’t matter if that secret is stored: In your local machine In an Azure KeyVault In HashiCorp Vault In KeePass, LastPass etc. The mindset remains the same ‘One remote control, to control them all’. The architecture behind it looks a bit like below; Explaination: SecretManagement “The interface where you code against” SecretStore “The default storage where your secrets live” Getting Started Let’s get started! Start PowerShell 7+ and run the code below Install-Module Microsoft.PowerShell.SecretManagement -Repository PSGallery -Force Install-Module Microsoft.PowerShell.SecretStore -Repository PSGallery -Force Now we have the required modules installed form the PowerShell Gallery it’s time to create our first vault. Register-SecretVault -name "LocalTestVault" It will ask you for the module. Enter the name “Microsoft.PowerShell.SecretStore”. (If you want you can also specify this value directly in the CMDLet by specifying the -ModuleName parameter. You should end up with something like below: First secrets Now we have the vault set-up it’s time to add some content to it. Follow the steps below to create the first secret in the vault Run the command below to create the first secret Set-Secret -Name "TestSecret" -Secret "SuperDuperSecureSecretString" If you haven’t specified the password it will now ask for one! You should end up with something like below; Cool right? On my personal blog I have the full post where I also show how to change, delete, and store complex objects. You can find it here: https://bartpasmans.tech/powershell-stop-hardcoding-secrets-now-what/ Happy scripting!Bart_PasmansOct 13, 2025Copper Contributor27Views0likes0CommentsCan't add device member in Static Security Entra Group with powershell
Hi, With Graph, I want to add some device members in a static security Entra group using it to deploy some certificates with Intune. I do it with following command: New-MgGroupMember -GroupId $groupId -DirectoryObjectId $device.AzureAdDeviceId but I receive this error: New-MgGroupMember : Resource 'df75dfe1-8b5a-4cc6-8f99-17746bb8c07e' does not exist or one of its queried reference-property objects are not present. In C:\Users\E21996\OneDrive - Fondazione Enasarco\Lavoro\!HelpDesk\!Intune\Scripts\Set-Device-Department-Attribute.ps1:57 car:9 + New-MgGroupMember -GroupId $groupId -DirectoryObjectId $devic ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: ({ GroupId = 9fa...ferenceCreate }:<>f__AnonymousType1`2) [New-MgGroupMember_CreateExpanded], Exception + FullyQualifiedErrorId : Request_ResourceNotFound,Microsoft.Graph.PowerShell.Cmdlets.NewMgGroupMember_CreateExpanded I've checked the GroupID and Azure Device ID and are correct. If I try to add a user it works fine, with device I have this error. In the group I can add device member manually from Intune without problems. There is a known issue when add device members to groups in Graph? Can anyone help me to resolve this issue, please?LUCA NAVIGLIOOct 09, 2025Copper Contributor115Views0likes2CommentsNew-MgBookingBusinessService | Turn Customer Information Questions Off
I'm trying to turn off the stock Customer information questions except for customer email but cannot find how to do it? Any support is much appreciated. Below is what I've recently tried... # Prompt for Booking Business ID $bookingBusinessId = Read-Host "Enter the Booking Business ID (e.g., email address removed for privacy reasons)" # Prompt for default duration in minutes $defaultDurationMinutes = Read-Host "Enter default appointment duration in minutes (e.g., 15)" $defaultDuration = [TimeSpan]::FromMinutes([double]$defaultDurationMinutes) # Post-buffer stays at 5 minutes $postBuffer = [TimeSpan]::FromMinutes(5) # Hardcoded Excel file path $excelFilePath = "C:\Users\apettit\OneDrive - Eau Claire Area School District\Downloads\adamtestconferencedata.xlsx" # Prompt for worksheet/tab name $sheetName = Read-Host "Enter the worksheet/tab name to read data from" # Import Excel data using Import-Excel (requires ImportExcel module) if (-not (Get-Module -ListAvailable -Name ImportExcel)) { Install-Module -Name ImportExcel -Scope CurrentUser -Force } Import-Module ImportExcel $staffEmails = Import-Excel -Path $excelFilePath -WorksheetName $sheetName # Retrieve all staff members for the booking business Write-Host "Fetching all staff members for booking business ID: $bookingBusinessId" $allStaff = Get-MgBookingBusinessStaffMember -BookingBusinessId $bookingBusinessId if (-not $allStaff) { Write-Error "No staff members found for the booking business ID: $bookingBusinessId" return } # Retrieve all custom questions Write-Host "Fetching all custom questions for booking business ID: $bookingBusinessId" $allCustomQuestions = Get-MgBookingBusinessCustomQuestion -BookingBusinessId $bookingBusinessId if (-not $allCustomQuestions) { Write-Error "No custom questions found for the booking business ID: $bookingBusinessId" return } # Loop through each staff member from Excel automatically Write-Host "Creating individual booking services for each staff member..." foreach ($row in $staffEmails) { $email = $row.emailAddress.Trim().ToLower() # Automatically match staff from Booking Business $matchingStaff = $allStaff | Where-Object { $_.AdditionalProperties["emailAddress"] -and ($_.AdditionalProperties["emailAddress"].Trim().ToLower() -eq $email) } if ($matchingStaff) { $staffId = $matchingStaff.Id $displayName = $matchingStaff.AdditionalProperties["displayName"] Write-Host "Automatically creating service for: ${displayName} ($email)" -ForegroundColor Cyan try { # Prepare custom questions $customQuestions = $allCustomQuestions | ForEach-Object -Begin { $isLast = $false } -Process { $isLast = ($_.Id -eq $allCustomQuestions[-1].Id) $questionAssignment = New-Object Microsoft.Graph.PowerShell.Models.MicrosoftGraphBookingQuestionAssignment $questionAssignment.QuestionId = $_.Id $questionAssignment.IsRequired = if ($isLast) { $false } else { $true } $questionAssignment } # Prepare the reminder $defaultReminder = New-Object Microsoft.Graph.PowerShell.Models.MicrosoftGraphBookingReminder $defaultReminder.Message = "Don't forget! Family Teacher Conferences are tomorrow, and we are excited to visit with you! If you wish to change the meeting type (virtual, in-person, hybrid, or phone), please let the teacher know as soon as possible!" $defaultReminder.Offset = [TimeSpan]::FromDays(1) $defaultReminder.Recipients = @("customer") # Prepare service parameters $serviceParams = @{ BookingBusinessId = $bookingBusinessId DisplayName = "${displayName} Family Conference" Description = "Family Teacher Conference with ${displayName}" StaffMemberIds = @($staffId) # Assign specific staff member DefaultDuration = $defaultDuration DefaultPrice = 0.00 DefaultPriceType = "free" CustomQuestions = $customQuestions PostBuffer = $postBuffer IsLocationOnline = $true IsCustomerAllowedToManageBooking = $true DefaultReminder = $defaultReminder AdditionalInformation = @" Please arrive on time for your conferences as we will be sticking to a tight schedule. If you wish to change the meeting type (virtual, in-person, hybrid, or phone), please let the teacher know as soon as possible. If you require a translator, please submit a request at this form: https://forms.office.com/r/ "@ # Appears in the customer confirmation email } # Log service parameters Write-Host "Service Parameters for ${displayName}:" -ForegroundColor Blue $serviceParams.GetEnumerator() | ForEach-Object { Write-Host "$($_.Key): $($_.Value)" } # Create the booking service New-MgBookingBusinessService @serviceParams Write-Host "Booking service successfully created for ${displayName}!" -ForegroundColor Green } catch { Write-Error "Failed to create booking service for ${displayName}: $_" } } else { Write-Warning "No match found for email: $email" } }AP_TC_ECASDOct 05, 2025Brass Contributor49Views0likes2CommentsCreating Claims Mapping Policy in Entra ID
I am attempting to create a Claims Mapping Policy using PowerShell, Entra ID and Microsoft Graph via a script or a PowerShell Window, In neither case, I was able to do it. The script is: # Define the Application (Client) ID and Secret $applicationClientId = 'XXXXXXXXXXX' # Application (Client) ID $applicationClientSecret = 'XXXXXXXXXXX' # Application Secret Value $tenantId = 'XXXXXXXXXXXX' # Tenant ID Connect-Entra -TenantId $tenantId -ClientSecretCredential $clientSecretCredential $params = @{ definition = @( '{"ClaimsMappingPolicy":{"Version":1,"IncludeBasicClaimSet":"false","ClaimsSchema":[{"Source":"user","onpremisesssamaccountname":"name","SamlClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"}]}}' ) displayName = "ClaimTest" } New-MgPolicyClaimMappingPolicy -BodyParameter $params Get-MgPolicyClaimMappingPolicy Disconnect-Entra I keep getting the error: New-MgPolicyClaimMappingPolicy : One or more errors occurred. At C:\Users\eigog\Documents\Poweshell Scripts\test.ps1:24 char:1 + New-MgPolicyClaimMappingPolicy -BodyParameter $params + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [New-MgPolicyClaimMappingPolicy_Create], AggregateException + FullyQualifiedErrorId : System.AggregateException,Microsoft.Graph.PowerShell.Cmdlets.NewMgPolicyClaimMappingPolicy_Create I don't understand, because this was similar to the example they gave here: https://learn.microsoft.com/en-us/entra/identity-platform/claims-customization-powershell And yes, I tried to do it manually in a PowerShell window with my credentials and I tried the beta version as well. The application does have the scope of Policy.ReadWrite.ApplicationConfiguration. I can't seem to see the error. Can anyone see something I'm missing or point me in a direction? ThanksSolvedMustangProgrammerSep 30, 2025Copper Contributor44Views0likes1CommentWhy 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?kcelmerSep 23, 2025Brass Contributor99Views0likes4Comments
Resources
Tags
- Windows PowerShell1,191 Topics
- powershell345 Topics
- office 365280 Topics
- azure active directory145 Topics
- sharepoint131 Topics
- windows server129 Topics
- azure99 Topics
- exchange97 Topics
- community54 Topics
- azure automation50 Topics