azure automation
49 TopicsAssigning a Manager with PowerShell Graph – Manager Not Found
Hi everyone, We are currently refactoring our PowerShell scripts to align with Microsoft's recommended standards. In our script that creates new users in Azure Active Directory (AAD) via Microsoft Graph, we’re having trouble assigning a manager to a new user. Whether we try using the manager’s object ID or email address, the manager is not found, and the assignment fails. Has anyone encountered this issue before? Is there something we might be doing wrong in how we’re referencing or assigning the manager? Thanks in advance for your help.110Views0likes3CommentsGui 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."33Views0likes0CommentsAd-Hoc Entra MFA using SMS
Error : Get MFA Client Access TokenDone. Send MFA challenge to the user Done. OTP sent to your phone. Please enter the OTP: Enter the OTP sent via SMS: 696632 Invoke-RestMethod: C:\Git_Repo\MFA_Test\MFATestWIthKyle\sms.ps1:54:28 Line | 54 | … ionResult = Invoke-RestMethod -Uri 'https://strongauthenticationservi … | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Service BODY { color: #000000; background-color: white; font-family: Verdana; margin-left: 0px; margin-top: 0px; | } #content { margin-left: 30px; font-size: .70em; padding-bottom: 2em; } A:link { color: #336699; font-weight: bold; | text-decoration: underline; } A:visited { color: #6699cc; font-weight: bold; text-decoration: underline; } A:active { color: | #336699; font-weight: bold; text-decoration: underline; } .heading1 { background-color: #003366; border-bottom: #336699 6px | solid; color: #ffffff; font-family: Tahoma; font-size: 26px; font-weight: normal;margin: 0em 0em 10px -20px; padding-bottom: | 8px; padding-left: 30px;padding-top: 16px;} pre { font-size:small; background-color: #e5e5cc; padding: 5px; font-family: | Courier New; margin-top: 0px; border: 1px #f0f0e0 solid; white-space: pre-wrap; white-space: -pre-wrap; word-wrap: break-word; | } table { border-collapse: collapse; border-spacing: 0px; font-family: Verdana;} table th { border-right: 2px white solid; | border-bottom: 2px white solid; font-weight: bold; background-color: #cecf9c;} table td { border-right: 2px white solid; | border-bottom: 2px white solid; background-color: #e5e5cc;} Service Endpoint not found. WARNING: Invalid OTP or validation failed. Below line causing the error $mfaValidationResult = Invoke-RestMethod -Uri 'https://strongauthenticationservice.auth.microsoft.com/StrongAuthenticationService.svc/Connector//ValidatePin' -Method POST -Headers $Headers -Body $XML -ContentType 'application/xml'62Views0likes0Commentsfind the azure vm status in multiple subscription
We have multiple subscription (more than 10) in our environment and MFA enabled , I was trying to find one vm status using the name but its not working , setting azcontext with tenant ID also not working , I need command to set all subscription as context and find the vm status or any other way to find the vm status , this is needed for daily work, appreciate someone help on this .57Views0likes1CommentDoes Microsoft stop support WMIC or WMI?
Hello everyone, Nice to meet you! I heard that MS has plans to deprecate and stop supporting the VB script very soon. I have few queries, please clarify Does Microsoft stop supporting WMIC or WMI along with the VB script? Can we use WMI commands in PowerShell scripts? thanks Madhu85Views0likes1Comment[resolved] Variables are not consistent
Hello internet. My mind is completely blown by this! I have a PowerAutomate that sets some 'compose' actions and then uses them to start a job. It is a PowerShell 7.2 script running in a Runbook extension-based hybrid worker on a Debian 11 Azure VM. I've reduced the script to just printing the inputted variable values. That's all, yet it provides them transposed! param ( [string] $siteNAME, [string] $OMd, [string] $userNAME, [string] $templateNAME ) $scriptVERSION = "x.y.z" function WO { write-output $wriOU } write-output "----------------------------------" $wriOU = "siteNAME: "+$($siteNAME);WO $wriOU = "OMd: "+$($OMd);WO $wriOU = "userNAME: "+$($userNAME);WO $wriOU = "templateNAME: "+$($templateNAME);WO write-output "----------------------------------" $wriOU = "Script Version: [ "+$scriptVERSION+" ]";WO write-output "-end of line-" #EOF As you can see 'siteNAME' retains the value correctly. But then 'OMd', 'username', and 'templateNAME' goes sideways so hard... Why? What am I doing wrong, this seems super odd... Any insight is greaaaatly appreciated. TY!Solved426Views0likes2CommentsFacing error when running a ps script using mggraph
Hi Community, I am facing issue in fetching lastsignindate from azure ad using mggraph it returns error of 404 not found whereas user is present in azure ad. The script i am sharing has some fields blank for security reasons: # Function to authenticate with Microsoft Graph function Get-GraphToken { param ( [string]$tenantId, [string]$clientId, [string]$clientSecret, [string]$authUrl ) $authBody = @{ grant_type = "client_credentials" scope = "https://graph.microsoft.com/.default" client_id = $clientId client_secret = $clientSecret } try { $tokenResponse = Invoke-RestMethod -Method Post -Uri $authUrl -ContentType "application/x-www-form-urlencoded" -Body $authBody return $tokenResponse.access_token } catch { Write-Error "Failed to authenticate with Microsoft Graph: $_" return $null } } # Function to get the most recent LastLogon attribute from all domain controllers function Get-LastLogon { param ( [string]$userName ) $dcs = Get-ADDomainController -Filter * | Select-Object -ExpandProperty HostName $lastLogon = 0 foreach ($dc in $dcs) { try { $user = Get-ADUser $userName -Server $dc -Properties LastLogon if ($user.LastLogon -gt $lastLogon) { $lastLogon = $user.LastLogon } } catch { Write-Error "Failed to retrieve LastLogon from $dc for $userName $_" } } if ($lastLogon -ne 0) { return [DateTime]::FromFileTime($lastLogon) } else { return $null } } # Function to get last sign-in date from Azure AD using User ID function Get-UserLastSignIn { param ( [string]$userId, [hashtable]$headers ) try { # Get the user's sign-in activity using userId $userInfo = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users/$userId?$select=signInActivity" -Headers $headers if ($userInfo.signInActivity -and $userInfo.signInActivity.lastSignInDateTime) { # Return the lastSignInDateTime return [DateTime]::Parse($userInfo.signInActivity.lastSignInDateTime) } else { Write-Warning "No sign-in activity available for user with ID $userId." return $null } } catch { Write-Error "Failed to retrieve sign-in data for user with ID $userId $_" return $null } } # Function to send notification function Send-Notification { param ( [string]$userEmail, [string]$managerEmail ) $subject = "Login Reminder" $body = "You have not logged in for the past 10 days. Please log in to avoid account deactivation." # Uncomment the below line to send the actual email # Send-MailMessage -From "" -To $userEmail -Cc $managerEmail -Subject $subject -Body $body -SmtpServer $smtpServer } # Function to create and send the HTML report function Create-And-Send-HTMLReport { param ( [array]$csvData, [string]$htmlReportPath ) $htmlContent = @" <html> <head> <title>User Login Report</title> <style> table { width: 100%; border-collapse: collapse; } table, th, td { border: 1px solid black; } th, td { padding: 8px; text-align: left; } </style> </head> <body> <h2>User Login Report</h2> <table> <tr> <th>samAccountName</th> <th>DisplayName</th> <th>MailSentToManager</th> <th>LastLogonOnPrem</th> <th>LastLogonAzureAD</th> <th>SessionRevoked</th> <th>Action</th> </tr> "@ foreach ($row in $csvData) { $htmlContent += "<tr>" $htmlContent += "<td>$($row.samAccountName)</td>" $htmlContent += "<td>$($row.DisplayName)</td>" $htmlContent += "<td>$($row.MailSentToManager)</td>" $htmlContent += "<td>$($row.LastLogonOnPrem)</td>" $htmlContent += "<td>$($row.LastLogonAzureAD)</td>" $htmlContent += "<td>$($row.SessionRevoked)</td>" $htmlContent += "<td>$($row.Action)</td>" $htmlContent += "</tr>" } $htmlContent += @" </table> </body> </html> "@ # Save the HTML content to a file $htmlContent | Out-File -FilePath $htmlReportPath -Encoding UTF8 # Uncomment the below line to send the actual email # Send-MailMessage -From "" -To "" -Subject "Daily User Login HTML Report" -BodyAsHtml -Body $htmlContent -SmtpServer $smtpServer } # Function to send daily report to IT function Send-DailyReport { param ( [string]$reportPath ) $subject = "Daily User Login Report" $body = Get-Content -Path $reportPath -Raw # Uncomment the below line to send the actual email # Send-MailMessage -From "" -To "" -Subject $subject -Body $body -BodyAsHtml -SmtpServer $smtpServer -Port $smtpPort } # Main script starts here # Define variables $tenantId = "" $clientSecret = "" $clientId = "" $authUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" $smtpServer = "" $smtpPort = $departmentsFilePath = "C:\psscr\Departments.txt" # Authenticate with Microsoft Graph $token = Get-GraphToken -tenantId $tenantId -clientId $clientId -clientSecret $clientSecret -authUrl $authUrl # Ensure that the token was successfully obtained if (-not $token) { Write-Error "Failed to obtain Microsoft Graph token. Exiting script." exit } $headers = @{ Authorization = "Bearer $token" } # Set cut-off dates $cutOffDate10Days = (Get-Date).AddDays(-10) $cutOffDate15Days = (Get-Date).AddDays(-15) # Check departments $departments = Get-Content -Path $departmentsFilePath # Initialize CSV report $currentDateTime = (Get-Date).ToString("dd-MM-yyyy_HH-mm") $csvFilePath = "C:\psscr\DailyUserLoginReport_$currentDateTime.csv" $htmlReportPath = "C:\psscr\DailyUserLoginReport_$currentDateTime.html" $csvData = @() # Process each department foreach ($dept in $departments) { $users = Get-ADUser -Filter { Department -eq $dept } -Properties LastLogonTimestamp, Manager, Enabled, UserPrincipalName, DisplayName foreach ($user in $users) { if (-not $user.Enabled) { continue } # Get the most recent LastLogon from AD $lastLogon = Get-LastLogon -userName $user.SamAccountName $lastLogonString = if ($lastLogon) { $lastLogon.ToString("yyyy-MM-dd HH:mm:ss") } else { "Never" } # Get the user's Azure AD ID $userResponse = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users?$filter=userPrincipalName eq '$($user.UserPrincipalName)'" -Headers $headers # Find the user with the exact UserPrincipalName match $userId = $null foreach ($responseUser in $userResponse.value) { if ($responseUser.userPrincipalName -eq $user.UserPrincipalName) { $userId = $responseUser.id break } } #$userId = $userResponse.value[$user.UserPrincipalName].id # Ensure that a valid userId was retrieved if ($null -eq $userId) { Write-Warning "Could not retrieve userId for $($user.UserPrincipalName). Skipping..." continue } # Get the most recent last sign-in date from Azure AD using ID $lastSignInDate = Get-UserLastSignIn -userId $userId -headers $headers $lastSignInDateString = if ($lastSignInDate) { $lastSignInDate.ToString("yyyy-MM-dd HH:mm:ss") } else { "Never" } $action = "" $mailSent = $false $sessionRevoked = $false if ($lastLogon -lt $cutOffDate10Days -and $lastSignInDate -lt $cutOffDate10Days) { # Send notification to the user and manager $manager = Get-ADUser -Identity $user.Manager -Properties EmailAddress Send-Notification -userEmail $user.EmailAddress -managerEmail $manager.EmailAddress $mailSent = $true } if ($lastLogon -lt $cutOffDate15Days -and $lastSignInDate -lt $cutOffDate15Days) { # Revoke Azure AD sessions and disable the on-premises AD account # Uncomment the below line to revoke Azure AD sessions # Invoke-RestMethod -Method Post -Uri "https://graph.microsoft.com/v1.0/users/$userId/revokeSignInSessions" -Headers $headers #Disable-ADAccount -Identity $user.SamAccountName $action = "Account Disabled" $sessionRevoked = $true } $csvData += [pscustomobject]@{ samAccountName = $user.SamAccountName DisplayName = $user.DisplayName MailSentToManager = $mailSent LastLogonOnPrem = $lastLogonString LastLogonAzureAD = $lastSignInDateString SessionRevoked = $sessionRevoked Action = $action } } } # Export to CSV $csvData | Export-Csv -Path $csvFilePath -NoTypeInformation # Create and send the HTML report Create-And-Send-HTMLReport -csvData $csvData -htmlReportPath $htmlReportPath # Send the daily report to IT Send-DailyReport -reportPath $htmlReportPath Any help is appreciated why this error occurs is known to us that it is not found will this need changes in script or something else. The permissions given to Azure app is correct as is does not show permission error when running the script.Solved537Views0likes6CommentsStart-AzAutomationRunbook : Invalid runbook parameters.
Hi Team, My PowerShell Script trying to run a Runbook job using Runbook Hybrid worker group gives this error: Start-AzAutomationRunbook : Invalid runbook parameters. This happens when I am trying to pass parameter such as website name. Any help will be great. Clear-AzContext -Force Import-Module Az.Accounts Import-Module Az.Automation $Secret = "" $AppId = "" $TenantID = "" $SecurePass = ConvertTo-SecureString $Secret -AsPlainText -Force $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AppId, $SecurePass Connect-AzAccount -ServicePrincipal -Tenant $TenantID -Credential $Credential #$IIS = "bill36" #$Redi = "https://www.google.com" $parameters= [ordered]@{'SiteName' = 'bill36' ; Redirect = 'https://www.google.com'} $resourceGroupName = "OnPrem-Automation" $automationAccountName = "AzOnPrem-Automation" $runbookName1 = "US03wredirect-IIS" $hybridWorkerGroupName1 = "OnPrem-Automation" $runbookName2 = "US01WREDIRECT111-IIS-OnPrem-Automation1" $hybridWorkerGroupName2 = "OnPrem-Automation1" $job1 = Start-AzAutomationRunbook -ResourceGroupName $resourceGroupName -AutomationAccountName $automationAccountName -Name $runbookName1 -Parameters $parameters -RunOn $hybridWorkerGroupName1 -debug #$job2 = Start-AzAutomationRunbook -ResourceGroupName $resourceGroupName -AutomationAccountName $automationAccountName -Name $runbookName2 -Parameters $params2 -RunOn $hybridWorkerGroupName2293Views0likes0CommentsFabric API: Update user scopes
Context: The token I generated was retrieved by logging in with 'Login-PowerBI', followed by "Get-PowerBiAccessToken -asstring" inside of Powershell. This token was then copied and used inside of postman for the authorization. I didn't use any extra parameters. Since the current usage of a Service Principal is quite limited for the Fabric API, we're opting to use the personal bearer token. Scenario: At our company we're trying to experiment a bit with the MS Fabric API (https://api.fabric.microsoft.com). With the service principal token, we've been able to use the API to list the workspaces, items, ... basically most standard get calls you could imagine. But, it doesn't support creating items yet via the service principal. So, we had to switch to the usage of a personal user token. We are able to create workspaces via my individual token, but I'm unable to create individual items inside of a workspace. This is due to the fact that I don't have any individual item level scopes assigned to me for now. My current scopes are: "App.Read.All Capacity.Read.All Capacity.ReadWrite.All Content.Create Dashboard.Read.All Dashboard.ReadWrite.All Dataflow.Read.All Dataflow.ReadWrite.All Dataset.Read.All Dataset.ReadWrite.All Gateway.Read.All Gateway.ReadWrite.All Pipeline.Deploy Pipeline.Read.All Pipeline.ReadWrite.All Report.Read.All Report.ReadWrite.All StorageAccount.Read.All StorageAccount.ReadWrite.All Tenant.Read.All Tenant.ReadWrite.All UserState.ReadWrite.All Workspace.Read.All Workspace.ReadWrite.All" As you can see, it's quite normal that I'm only able to create a Workspace. But I want to be able to assign e.g. "Notebook.ReadWrite.All" to my user. How do I do this for an individual user? I'm trying to automate as much as possible using Powershell scripts, but the current scopes are quite limited. Goal: Using a personal bearer token (not generated through a service principal) to create a notebook item. Endpoint: https://learn.microsoft.com/en-us/rest/api/fabric/core/items/create-item?tabs=HTTP Question: Is it possible to do this without the usage of a service principal? I know you can use the copy(PowerBIAccessToken) inside of the dev-tools in your browser, but I want to do it more automatically. Hopefully this is the right section to ask such things, and thank you in advance for your help!395Views0likes0CommentsNeed to use SPO Service Online Powershell Module without credentials-based login for an Automation
I need to access the Sharepoint Admin Center via a Powershell Runbook through a Power Automate flow in order to perform hourly checks on Site Storage Usage in Sharepoint. I have a runbook that currently gets this data on a folder-basis with the PnP Module, but i'm unsure if this will work for this issue. My assumption is that i'll need to use the SPO Service module, but it requires credentials-based login with administrative access. Is there a way to circumvent this?364Views0likes2Comments