Invoke-AzureRmVMRunCommand not returning anything in "Output" field when executing from Runbook - powershell

I'm trying to invoke a powershell script on to a Virtual Machine and retrieve the output of the script. I'm using the Invoke-AzureRmVMRunCommand cmdlet to invoke the script on the VM as shown below.
$ValidationResult = Invoke-AzureRmVMRunCommand -ResourceGroupName $VM.ResourceGroupName -VMName $VM.Name -CommandId "RunPowerShellScript" -ScriptPath $ValidationScript
When I execute the above cmdlet from a regular powershell terminal, I get the output as expected. However, whenever I'm putting this statement inside an automation runbook, I get null in almost all the fields as shown below
I don't see anything specific to this in documentation as well. Am I doing something wrong here?
Any help would be greatly appreciated! Thank you.
Update:
In the script, I'm logging the output using Write-Output cmdlet.

You need to either add the object name on last line of your script or use the Write-Output command. Otherwise it will not output anything.
The following lines both write an object to the output stream.
Write-Output –InputObject $ValidationResult
$ValidationResult
https://learn.microsoft.com/en-us/azure/automation/automation-runbook-output-and-messages
Hope this helps

This issue is most likely due to a reported bug in the AzureRM modules starting with version 5.7.0 / April 2018. Rolling back to version 5.6.0 / March 2018 is reported to fix it. Issue log: https://github.com/Azure/azure-powershell/issues/5982

My Apologies for the delayed response. I was using this in a runbook of type Powershell Workflow. Many of the PowerShell cmdlets behave differently when executed in workflows.
So in this case, what was happening is the Invoke-AzureRmVMRunCommand was executing correctly but the response was only the TYPE of the response and not the actual response object. Hence I was unable to see any values in the response's properties.
In order to make this work, I had to wrap the cmdlet call within an InlineScript {} block.
$ValidationResult = InlineScript {
$result = Invoke-AzureRmVMRunCommand -ResourceGroupName $USING:VM.ResourceGroupName -VMName $USING:VM.Name -CommandId "RunPowerShellScript" -ScriptPath $USING:ValidationScript
$result.SubStatuses[0].Message
}
The result is returned to $ValidationResult variable.
More detailed post is given here: https://amoghnatu.net/2018/04/15/get-output-of-script-executed-as-part-of-set-azurermvmcustomscriptexecution-cmdlet/
Thanks.

Related

Can we call a runbook from another runbook in Powershell?

I'm having two runbooks of two different Powershell versions (5.1, 7.1). How to call a runbook (7.1) from runbook (5.1)?
Modules used:
AZ-SecurityInsights - 5.1 version (runbook 5.1)
AzSentinel - 7.1 version (runbook 7.1)
Need to pass resourcevariable as an input parameter to second runbook from first runbook.
My code:
$AzureContext = Set-AzContext -SubscriptionName $AzureContext.Subscription -DefaultProfile $AzureContext
Start-AzAutomationRunbook -AutomationAccountName $automationAccountName -Name "ExportAlertRule" -ResourceGroupName $automationResourceGroupName
Error:
Object reference not set to an instance of an object.
What can I try next?
If the output stream of Start-AzAutomationAccount contains object, the command does not process the output stream correctly. For the same, you need to implement a polling logic, and use the Get-AzAutomationJobOutput cmdlet to retrieve the output.
For more information, refer below documents.
https://learn.microsoft.com/en-us/azure/automation/troubleshoot/runbooks#resolution-13
https://learn.microsoft.com/en-us/azure/automation/automation-child-runbooks#runbook-types

I cannot redirect or hide Get-VM output

So I have a line of code to retrieve the VMID from a hyper-v vm. Running on Server 2016 so it should be at least Powershell 5.0.
[string]$vmid = (Get-VM $VMName).VMID
Pulls out the ID just how I need. The problem is the script also prints out the full result of Get-VM. I cannot for the life of me figure out how to mute or redirect it.
[void] doesn't work cause I'm pulling it into a string.
*> $null, 2> $null, 1> $null all do nothing, and I've tried both in the parenthesis and after the expression.
Piping to Out-Null has no effect either in those locations.
Any idea how I'm supposed to hide this? I really don't need all this info.
On my hyper-v server I had to run
$vmid = (Get-VM $VMName).VMid.Guid
to save only the string to variable
The above command works for me, so it's probably somewhere else in your code that you are getting the unwanted output?
So instead of the above, I ended up defining a $vm variable when creating the VM, then using it in the operations below.
$vm = New-VM ...
...
[string]$vmid = $vm.VMID.GUID

AzureRmApiManagementContext: FormatException when used as parameter in cmdlet

I am trying to use some of the Azure Powershell cmdlets in the AzureRM.ApiManagement module. A lot of the cmdlets require a context parameter, which is PsApiManagementContext object.
Following the guidance I have created a context using the New-AzureRmApiManagementContext cmdlet:
$ApiMgmtContext = New-AzureRmApiManagementContext
-ResourceGroupName "MyResourceGroup"
-ServiceName "MyApimService"
I then pass the context as a parameter to the cmdlet:
Get-AzureRmApiManagementUser -Context $ApiMgmtContext
The problem is that I get an error back as follows:
Get-AzureRmApiManagementUser : FormatException: One more parameters were not formatted correctly
I have used Fiddler to inspect the request that it generates and I can see that the body of the request is empty, so there must be something wrong with the way the context object has been created, even though I have basically copied the example in the microsoft docs. I have logged into my Azure subscription using Login-AzureRmAccount and selected the correct subscription prior to trying to create the context.
What am I doing wrong in the creation of the context object?

DSC Script Resource's TestScript failing to return boolean

Trying to push DSC I'm hitting the following error:
Failure to get a valid result from the execution of TestScript. The Test script should return True or False.
Here's the TestScript:
return (Test-Path -Path "FullPath:\To\File")
A couple things I've tried:
The Script resource has a (unmanaged) service account's credentials specified in the Credential parameter. Thinking it might not have permissions to the directory, causing Test-Path to error, I launched powershell as the user on the target machine and ran the cmdlet. It returned False (as expected). I've since made sure that the configuration gives the account permissions to the folder anyways.
Thinking it might be some weird idiosyncrasy with returning the cmdlet, I tried assigning the cmdlet to a variable and returning that. No dice.
Any ideas would be appreciated.
Edit: Here's the full resource, for those curious. It's basically just a couple quick lines to pull a script out of source control and place it locally so that I can create a scheduled task to run said script. Casting the result to a bool didn't work (same error). I'm wondering if it's even getting inside the TestScript at this point...checking get-executionpolicy shows it as undefined for the account but at the userpolicy, machinepolicy and localmachine level they're all bypass.
Script NameOfScript {
DependsOn = "[cNtfsPermissionEntry]DirectoryPermissions"
Credential = $serviceAccountPSCredentialObject
SetScript = {
Import-Module -Name Subversion
New-SvnWorkingCopy -Url "https://svnrepourl/script.ps1" -Path "E:\Scripts\"
}
TestScript = {
[bool]$result
$result = Test-Path -Path "E:\Scripts\script.ps1" -ErrorAction Stop
return $result
}
GetScript = { }
}
Try this
return ([bool]$testPath = Test-Path -Path "FullPath:\To\File")
Figured it out, with the help of this forum post. Initially I didn't think it'd be much help since I shouldn't be experiencing double-hop issues, but I'll explain why it's germane below. #TravisEz13 made the comment that the Credential parameter isn't used, but that is incorrect.
If you look at the Script resource, when you specify credentials this is how it runs the script blocks:
$scriptExecutionResult = Invoke-Command -ScriptBlock $ScriptBlock -ComputerName . -Credential $Credential
The service account in question doesn't have remote access to the machine. So when I launch powershell locally as that user and run the Test-Path cmdlet, it works, but when I try to run the above Invoke-Command with that account's creds, it returns an access denied error.
My solution was to write a module/resource for subversion checkout. Not just to get around this, but also because the subversion powershell module I was using above doesn't provide a means to pass credentials to the svn binary.

Return code and status from PowerShell command

I'm running the following command from within a Microsoft System Centre Orchestrator PowerShell activity:
Install-WindowsFeature -ConfigurationFilePath C:\DeploymentConfigTemplate.xml -ComputerName ServerXYZ
the command isn't doing what it's supposed to do, and I want to be able to return if the command was successful or not, and any error message if possible. Ignore the fact it's running in Orchestrator, as I'm more concerned about the PowerShell question. When I run the command from ISE it does what it's supposed to do, that's why I want to see what is returned from PowerShell.
Thanks.
It's hard to know what may be happening without more context. The following will record any errors encountered in an xml file that you can import later with import-clixml:
Install-WindowsFeature -ConfigurationFilePath C:\DeploymentConfigTemplate.xml -ComputerName ServerXYZ
IF (!($?)) {
$error[0] | export-clixml C:\myerror.xml
}
This solves my problem:
$Result = Install-WindowsFeature -Name SNMP-Service -IncludeAllSubFeature -IncludeManagementTools
Write-Host $Result.ExitCode