Start-AzureRmAutomationRunbook is not accepting System.String parameter - powershell

I am trying to automate server reboot for one of our environment in Azure through azure automation.
I have created one runbook to know how many servers online.
Then trying pass the output as a parameter to another runbook and getting the
error.
below is the code.
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
$Output = #()
$Running_XenApps = #()
$Output = .\Test.ps1
Foreach ($out in $Output)
{
$Running_XenApps += $out.Name | Out-String
}
Start-AzureRmAutomationRunbook –AutomationAccountName 'acm2eo-azure- automation' -Name 'Server-Reboot' -ResourceGroupName 'acm2eo-automation' -Parameters $Running_Xenapps -Runon acm2eo-hybrid-group1
I am getting below error.
Start-AzureRmAutomationRunbook : Cannot convert 'System.Object[]' to the type 'System.Collections.IDictionary' requiredby parameter 'Parameters'. Specified method is not supported.
Please let me know how to convert this.
Thanks in Advance.

You have to pass a hashtable / dictionary to the -Parameter param:
$params = #{
"YourParameterName" = $Running_XenApps
}
Start-AzureRmAutomationRunbook –AutomationAccountName 'acm2eo-azure- automation' -Name 'Server-Reboot' -ResourceGroupName 'acm2eo-automation' -Parameters $params -Runon acm2eo-hybrid-group1
As documented here: Start-AzureRmAutomationRunbook cmdlet.

Related

How to create a schedule which triggers the runbook using PowerShell command?

I'm trying to create a schedule to trigger a runbook using PowerShell commands in Azure Automation account. Runbook is taking resourcevariable which is an automation variable as an input parameter.
I am able to create a schedule, but I am not able to register it as it is throwing the error:
Invalid runbook parameters
How can I register it and trigger a runbook ?
My code:
$TimeZone = ([System.TimeZoneInfo]::Local).Id
$scheduleName = "newschedule1"
$automationAccountName = "SentinelAutomationAccount"
$resourcegroupName = "myrg"
$RunbookName = "runbook1"
$params = #{"resourcevariable" = $resourcevariable;"flag" = $false}
$starttime = (Get-Date).AddMinutes(40)
$schedule = New-AzAutomationSchedule –AutomationAccountName $automationAccountName –Name $scheduleName –StartTime $starttime -OneTime -ResourceGroupName $resourcegroupName -TimeZone $TimeZone
Register-AzAutomationScheduledRunbook -AutomationAccountName $automationAccountName -RunbookName $RunbookName -ScheduleName $scheduleName -ResourceGroupName $resourcegroupName -Parameters $params
Runbook1 script: (5.1 version)
param (
[Parameter(Mandatory = $true)]
[string] $resourcevariable
)
# Login to Azure
try
{
"Logging in to Azure..."
Connect-AzAccount -Identity
}
catch {
Write-Error -Message $_.Exception
throw $_.Exception
}
$TimeZone = ([System.TimeZoneInfo]::Local).Id
$automationAccount = "xxxAutomationAccount"
$resourcegroup = "xxx"
$scheduleName = "myschedule"
$Runbook = "xxxRunBook"
$params = #{"resourcevariable" = "resourcevariable";"flag" = "false"}
$starttime = (Get-Date).AddMinutes(40)
$schedule = New-AzAutomationSchedule –AutomationAccountName $automationAccount –Name $scheduleName –StartTime $starttime -OneTime -ResourceGroupName $resourcegroup -TimeZone $TimeZone
Register-AzAutomationScheduledRunbook -AutomationAccountName $automationAccount -RunbookName $Runbook -ScheduleName $scheduleName -ResourceGroupName $resourcegroup -Parameters $params.Parameters
Runbook2 script: (7.1 version)
param (
[Parameter(Mandatory = $true)]
[string] $resourcevariable
)
# Login to Azure
try
{
"Logging in to Azure..."
Connect-AzAccount -Identity
}
catch {
Write-Error -Message $_.Exception
throw $_.Exception
}
echo "From Runbook2"
I tried it in my environment and found the same error.
When trying to retrieve parameters stored in the params variable, we should specify them as $params.parameters.
I modified the script and was able to correctly register and trigger the schedule.
Modified script:
$params = #{"resourcevariable" = "resourcevariable";"flag" = "false"}
Register-AzAutomationScheduledRunbook -AutomationAccountName $automationAccount -RunbookName $Runbook -ScheduleName $scheduleName -ResourceGroupName $resourcegroup -Parameters $params.Parameters
myschedule.ps1:
$TimeZone = ([System.TimeZoneInfo]::Local).Id
$automationAccount = "xxxxautomationaccount"
$resourcegroup = "xxxResourcegroup"
$scheduleName = "xxxxxschedule"
$Runbook = "xxxxrunbook"
$params = #{"resourcevariable" = "resourcevariable";"flag" = "false"}
$starttime = (Get-Date).AddMinutes(40)
$schedule = New-AzAutomationSchedule –AutomationAccountName $automationAccount –Name $scheduleName –StartTime $starttime -OneTime -ResourceGroupName $resourcegroup -TimeZone $TimeZone
Output:
Scheduled in Portal successfully:
Note: Run the same script in runbook with the changes given above to get the same results.

Sorting contents with a PS script

Goal of this post:
Sort Name column with csv filter -contains "-POS-"
Only pull back the top Bitlocker key from AzureAD and place that one key into the bitlockerKeys column.
This is a script from - https://gitlab.com/Lieben/assortedFunctions/blob/master/get-bitlockerEscrowStatusForAzureADDevices.ps1
This is not my script, but I need it to work like this for a project I am doing. Did I mention that I am a complete PS noob here? Take it easy on me please lol.
function get-bitlockerEscrowStatusForAzureADDevices{
#Requires -Modules ImportExcel
<#
.SYNOPSIS
Retrieves bitlocker key upload status for all azure ad devices
.DESCRIPTION
Use this report to determine which of your devices have backed up their bitlocker key to AzureAD (and find those that haven't and are at risk of data loss!).
Report will be stored in current folder.
.EXAMPLE
get-bitlockerEscrowStatusForAzureADDevices
.PARAMETER Credential
Optional, pass a credential object to automatically sign in to Azure AD. Global Admin permissions required
.PARAMETER showBitlockerKeysInReport
Switch, is supplied, will show the actual recovery keys in the report. Be careful where you distribute the report to if you use this
.PARAMETER showAllOSTypesInReport
By default, only the Windows OS is reported on, if for some reason you like the additional information this report gives you about devices in general, you can add this switch to show all OS types
.NOTES
filename: get-bitlockerEscrowStatusForAzureADDevices.ps1
author: Jos Lieben
blog: www.lieben.nu
created: 9/4/2019
#>
[cmdletbinding()]
Param(
$Credential,
[Switch]$showBitlockerKeysInReport,
[Switch]$showAllOSTypesInReport
)
Import-Module AzureRM.Profile
if (Get-Module -Name "AzureADPreview" -ListAvailable) {
Import-Module AzureADPreview
} elseif (Get-Module -Name "AzureAD" -ListAvailable) {
Import-Module AzureAD
}
if ($Credential) {
Try {
Connect-AzureAD -Credential $Credential -ErrorAction Stop | Out-Null
} Catch {
Write-Warning "Couldn't connect to Azure AD non-interactively, trying interactively."
Connect-AzureAD -TenantId $(($Credential.UserName.Split("#"))[1]) -ErrorAction Stop | Out-Null
}
Try {
Login-AzureRmAccount -Credential $Credential -ErrorAction Stop | Out-Null
} Catch {
Write-Warning "Couldn't connect to Azure RM non-interactively, trying interactively."
Login-AzureRmAccount -TenantId $(($Credential.UserName.Split("#"))[1]) -ErrorAction Stop | Out-Null
}
} else {
Login-AzureRmAccount -ErrorAction Stop | Out-Null
}
$context = Get-AzureRmContext
$tenantId = $context.Tenant.Id
$refreshToken = #($context.TokenCache.ReadItems() | where {$_.tenantId -eq $tenantId -and $_.ExpiresOn -gt (Get-Date)})[0].RefreshToken
$body = "grant_type=refresh_token&refresh_token=$($refreshToken)&resource=74658136-14ec-4630-ad9b-26e160ff0fc6"
$apiToken = Invoke-RestMethod "https://login.windows.net/$tenantId/oauth2/token" -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded'
$restHeader = #{
'Authorization' = 'Bearer ' + $apiToken.access_token
'X-Requested-With'= 'XMLHttpRequest'
'x-ms-client-request-id'= [guid]::NewGuid()
'x-ms-correlation-id' = [guid]::NewGuid()
}
Write-Verbose "Connected, retrieving devices..."
$restResult = Invoke-RestMethod -Method GET -UseBasicParsing -Uri "https://main.iam.ad.ext.azure.com/api/Devices?nextLink=&queryParams=%7B%22searchText%22%3A%22%22%7D&top=15" -Headers $restHeader
$allDevices = #()
$allDevices += $restResult.value
while($restResult.nextLink){
$restResult = Invoke-RestMethod -Method GET -UseBasicParsing -Uri "https://main.iam.ad.ext.azure.com/api/Devices?nextLink=$([System.Web.HttpUtility]::UrlEncode($restResult.nextLink))&queryParams=%7B%22searchText%22%3A%22%22%7D&top=15" -Headers $restHeader
$allDevices += $restResult.value
}
Write-Verbose "Retrieved $($allDevices.Count) devices from AzureAD, processing information..."
$csvEntries = #()
foreach($device in $allDevices){
if(!$showAllOSTypesInReport -and $device.deviceOSType -notlike "Windows*"){
Continue
}
$keysKnownToAzure = $False
$osDriveEncrypted = $False
$lastKeyUploadDate = $Null
if($device.deviceOSType -eq "Windows" -and $device.bitLockerKey.Count -gt 0){
$keysKnownToAzure = $True
$keys = $device.bitLockerKey | Sort-Object -Property creationTime -Descending
if($keys.driveType -contains "Operating system drive"){
$osDriveEncrypted = $True
}
$lastKeyUploadDate = $keys[0].creationTime
if($showBitlockerKeysInReport){
$bitlockerKeys = ""
foreach($key in $device.bitlockerKey){
$bitlockerKeys += "$($key.creationTime)|$($key.driveType)|$($key.recoveryKey)|"
}
}else{
$bitlockerKeys = "HIDDEN FROM REPORT: READ INSTRUCTIONS TO REVEAL KEYS"
}
}else{
$bitlockerKeys = "NOT UPLOADED YET OR N/A"
}
$csvEntries += [PSCustomObject]#{"Name"=$device.displayName;"bitlockerKeys"=$bitlockerKeys}
}
$csvEntries | Export-Excel -workSheetName "BitlockerKeyReport" -path "C:\BitLockerKeyReport.xlsx" -ClearSheet -TableName "BitlockerKeyReport" -AutoSize -Verbose
}
get-bitlockerEscrowStatusForAzureADDevices -showBitlockerKeysInReport

Azure Runbook (workflow) output result to Table

I'm recreating an Azure Runbook to coincide with a Logic App functionality. Long story short, I want the Logic App to initiate the Runbook, grab the results from the Runbook and use them for the next steps in the Logic App.
Initially I wanted to grab the JSON output of starting some VMs, where I ended up with the output being like this:
{
"MyVM2": true
}
{
"MyVM1": true
}
I was then going to Parse the JSON to be used in the Runbook, but soon realising that I would not have a consisted number of results (maybe 2 VMs, or 20) I had found the Parse JSON schema to only Parse what I set the schema to be (2, in my case, so anything more would be missed).
Now I figure I could put my output to a table, then use that to allow the Logic App to look inside that table to pull my VM names and success results from. So, here is the Runbook that I've been mutilating:
workflow ShutDownStartByTagasdf
{
Param(
[Parameter(Mandatory=$true)]
[String]
$TagName,
[Parameter(Mandatory=$true)]
[String]
$TagValue,
[Parameter(Mandatory=$true)]
[Boolean]
$Shutdown
)
$connectionName = "AzureRunAsConnection";
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
# Logging in to Azure
$null = Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
$vms = Find-AzureRmResource -TagName $TagName -TagValue $TagValue | where {$_.ResourceType -like "Microsoft.Compute/virtualMachines"}
Foreach -Parallel ($vm in $vms){
if($Shutdown){
$StopRtn = Stop-AzureRmVm -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -Force;
$objOut = [PSCustomObject]#{
VM = $vm.Name
Success = $StartRtn.IsSuccessStatusCode
}
}
else {
$StartRtn = Start-AzureRmVm -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName;
$objOut = New-Object psobject -Property #{
VM = $vm.Name
Success = $StartRtn.IsSuccessStatusCode
}
}
$outPut = InlineScript {
$Using:objOut | Format-Table Vm,Success
}
}
}
Ignore the $objOut = [PSCustomObject]#{ part, that's just history of my JSON messing about, and I'm leaving it there for now because I'm not using the $Shutdwon = $True, only $False, which is the very last part after else {
this bit:
else {
$StartRtn = Start-AzureRmVm -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName;
$objOut = New-Object psobject -Property #{
VM = $vm.Name
Success = $StartRtn.IsSuccessStatusCode
}
}
$outPut = InlineScript {
$Using:objOut | Format-Table Vm,Success
}
}
I was trying to implement something along the lines of what is already described here: Create Table with Variables in PowerShell
But there is no Output into the Azure Runbook console, but it does boot the VMs.
A very long winded explanation, but does anyone know how I could output to a Formatted Table inside a Workflow (Runbook) that will yield all my results in one table?
I ended up using an array to capture the info:
workflow ShutDownStartByTagasdf
{
Param(
[Parameter(Mandatory=$true)]
[String]
$TagName,
[Parameter(Mandatory=$true)]
[String]
$TagValue,
[Parameter(Mandatory=$true)]
[Boolean]
$Shutdown
)
$connectionName = "AzureRunAsConnection";
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
# "Logging in to Azure..."
$null = Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
$result_array = #()
$vms = Find-AzureRmResource -TagName $TagName -TagValue $TagValue | where {$_.ResourceType -like "Microsoft.Compute/virtualMachines"}
Foreach -Parallel ($vm in $vms) {
if($Shutdown){
# Write-Output "Stopping $($vm.Name)";
$StopRtn = Stop-AzureRmVm -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -Force;
$objOut = New-Object -TypeName psobject -Property #{
VM = $vm.Name
Success = $StopRtn.IsSuccessStatusCode
}
}
else {
# Write-Output "Starting $($vm.Name)";
$StartRtn = Start-AzureRmVm -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName;
$objOut = New-Object -TypeName psobject -Property #{
VM = $vm.Name
Success = $StartRtn.IsSuccessStatusCode
}
}
$workflow:result_array += $objOut
}
$result_array | ConvertTo-Json
}
The last bit $result_array | ConvertTo-Json allowed me to get a better output which I hope to use in the Logic App. The output:
[
{
"VM": "MyVM2",
"Success": true,
"PSComputerName": "localhost",
"PSShowComputerName": true,
"PSSourceJobInstanceId": "dadd87ad-1de1-432c-92b1-4c501c9a7ce8"
},
{
"VM": "MyVM1",
"Success": true,
"PSComputerName": "localhost",
"PSShowComputerName": true,
"PSSourceJobInstanceId": "dadd87ad-1de1-432c-92b1-4c501c9a7ce8"
}
]
I don't like how it's an array of objects, cos now I gotta figure out how to get some braces around it { } within the Logic App to utilise it better.

PowerShell script to process cube on Azure - connection issue

I am trying to process cube on Azure with Powershell script. Have this kind of code:
# PowerShell code
# Connect to a connection to get TenantId and SubscriptionId
$Connection = Get-AutomationConnection -Name "AzureRunAsConnection"
$TenantId = $Connection.TenantId
$SubscriptionId = $Connection.SubscriptionId
# Get the service principal credentials connected to the automation account.
#$null = $SPCredential = Get-AutomationPSCredential -Name "Samcred"
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
# Select the correct subscription
Write-Output "Selecting subscription '$($SubscriptionId)'."
$null = Select-AzureRmSubscription -SubscriptionID $SubscriptionId
# Get variable values
$DatabaseName = Get-AutomationVariable -Name 'DatabaseName'
$AnalysisServerName = Get-AutomationVariable -Name 'AnalysisServerName'
# Show info before processing (for testing/logging purpose only)
Write-Output "Processing $($DatabaseName) on $($AnalysisServerName)"
#Process database
$null = Invoke-ProcessASDatabase -databasename $DatabaseName -server $AnalysisServerName -RefreshType "Full" -Credential $SPCredential
# Show done when finished (for testing/logging purpose only)
Write-Output "Done"
After execution there is connection error:
Invoke-ProcessASDatabase : Authentication failed: User ID and Password are required when user interface is not
available.
At line:46 char:9
+ $null = Invoke-ProcessASDatabase -databasename $DatabaseName -server ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Invoke-ProcessASDatabase], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.AnalysisServices.PowerShell.Cmdlets.ProcessASDatabase
Using Microsoft SQL Analysis Server (version 15.0.0.52).
Somehow there is need again to put account and password, which I already done.

Error while running Azure runbook which executes PowerShell command on Virtual Machine

I am trying to execute this code in runbook, using "Invoke-Command" to connect to VM.
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure"
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
# Use the subscription that this Automation account is in
$null = Select-AzureRmSubscription -SubscriptionId $servicePrincipalConnection.SubscriptionID
Get-AzureRmVM | Select Name
$dcred = Get-AutomationPSCredential -Name 'myvm1creds'
Write-Output $DomainCred
$opts = New-PSSessionOption -SkipCACheck
Invoke-Command -Computername 'myVM1' -Credential $dcred -ScriptBlock {Get-Process} -SessionOption $opts
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
Getting the below error:
[myVM1] Connecting to remote server myVM1 failed with the following error message : The WinRM client cannot process the
request. If the authentication scheme is different from Kerberos, or if the client computer is not joined to a domain,
then HTTPS transport must be used or the destination machine must be added to the TrustedHosts configuration setting.
Use winrm.cmd to configure TrustedHosts. Note that computers in the TrustedHosts list might not be authenticated. You
can get more information about that by running the following command: winrm help config. For more information, see the
about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (myVM1:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : ServerNotTrusted,PSSessionStateBroken
Any idea what have to be done to run powershell script via runbook on Azure Virtual Machines
In Azure runbook, we can't use transport HTTP to connect Azure VMs, because Azure runbook can't add trust host, so we need use HTTPS to connect Azure VMs.
Here are my steps:
1.Create a self-signed certificate.
Use makecert.exe to create it.
2.Config Winrm listen on HTTPS, run this script in CMD:
winrm create winrm/config/Listener?Address=*+Transport=HTTPS #{Port="5986" ;Hostname="jasonvm" ;CertificateThumbprint="98941E137CDF9553CCB0C28D5814EB9EDB1AC87D"}
3.Add port 5986 in Azure NSG inbound rules and windows firewall inbound rules.
4.we can use this runbook to connect Azure VM:
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
$null = Select-AzureRmSubscription -SubscriptionId $servicePrincipalConnection.SubscriptionID
Get-AzureRmVM | Select Name
$dcred = Get-AutomationPSCredential -Name 'jasonvm'
Write-Output $DomainCred
$opts = New-PSSession -ConnectionUri 'https://52.185.148.177:5986' -Credential $dcred -SessionOption (New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck)
Invoke-Command -Session $opts -ScriptBlock {Get-Process}
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
Here is my result: