windows powershell
1199 TopicsConnect-SPOService not working in PowerShell 7
Hi all, I'm having some issues getting Connect-SPOService working in PowerShell 7 (7.2.4). It works fine in Windows PowerShell (5.1.22), however it will always generate errors when trying to us it in PS 7 which I've listed below. Firstly if I open Windows PS, I can use it straight away, however if I open PS 7, I have to import the module in order to use it. I guess I can fix this with a profile adjustment, but is there a reason why this would be the case? Secondly even when it's been imported, if I try to connect with the following, I get an error: Connect-SPOService -Url https://***-admin.sharepoint.com Connect-SPOService: No valid OAuth 2.0 authentication session exists Never seen this before in Windows PS and I'm not sure how to resolve it so I tried connecting with this instead. Still got an error but a different one this time: Connect-SPOService -Url https://***-admin.sharepoint.com -Credential ***@***.com Connect-SPOService: The sign-in name or password does not match one in the Microsoft account system. I know these are the right credientials as again they work fine in Windows PS. This lead me to think that something still wasn't being imported correctly into PS 7, so I had a look at the modes, and I noticed that the ExportedCommands don't appear when Get-Module is run in PS 7, but again they do in Windows PS. I'm guessing this could be part of the issue but I'm not sure how to resolve it. From what I can see everything appears fine, but I'm sure I'm missing something here. I've tried setting my ExecutionPolicy to unrestricted in case that was the problem, however it didn't appear to change anything. If anyone has seen this before or could provide any help it would be greatly appreciated. I realise that I could just use Windows PS, but it feels like PS 7 is the way forward and it would be nice to better understand why this is happening. Many thanks in advance.Solved43KViews0likes10CommentsHow to disable automatic updates in Debug Diagnostics 2.1 using PowerShell
Greetings all. I am writing a PowerShell script to do an unattended install of Debug Diagnostics Tool version 2.2.0.14. The installer is an x64 .msi. The unattended install works fine, but I am unable to find the correct switch/command to disable automatic updates for the tool. Here is the latest code I tried: Execute-MSI -Action 'Install' -Path "<filepath>\DebugDiagx64.msi" -Parameters "/qn /norestart ALLUSERS=2 DISABLE_AUTOUPDATES=1" Other switches I have tried for disabling updates includes DISABLE_UPDATES=1, UPDATES=0 and UPDATES=FALSE. None of these work. Updates can be disabled manually through the Options & Settings GUI. Screenshots for this are attached. I really need a way to disable the automatic updates through PowerShell during an unattended installation through SCCM . Thanks.Solved83Views0likes1CommentBug: 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, Lain173Views0likes4CommentsLaunch 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.133Views0likes3CommentsNew-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" } }79Views0likes1CommentSet 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? TIASolved137Views0likes1CommentStop 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!54Views1like0CommentsNew-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" } }94Views0likes2CommentsWhy 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?157Views0likes4Comments