none
Azure Automation - Calling a child cmdlet with function from a parent powershell script

    Question

  • Hi All,

    I'm new to the Azure Automation Runbook environment. I've had success creating a stand alone powershell script however I'm looking to create reusable codes hence I though I would try what I normally do in Windows Powershell ...creating scripts with functions and include these in a parent. However I've tried various methods with no success

    Below is my script that I would like to call or embed in a parent script. I saved and published this on my automation account. I also called the runbook ChangePipelineStatus. Hence the runbook's name is ChangePipelineStatus and has a function called ChangePipelineStatus inside it

    ChangePipelineStatus
    (
        [Parameter(Mandatory=$true)]
        [string]$StorageAccountKey,

        [Parameter(Mandatory=$true)]
        [string]$StorageAccountName,

        [Parameter(Mandatory=$true)]
        [string]$JsonConfigLocation,

        [Parameter(Mandatory=$true)]
        [string]$Action
    )
    {
        Write-Verbose $StorageAccountKey -Verbose
        Write-Verbose $StorageAccountName -Verbose
        Write-Verbose $JsonConfigLocation -Verbose
        Write-Verbose $Action -Verbose
    }

    The following is the parent script

    #Authenticate using the run as Account
    $Auth = Get-AutomationConnection -Name AzureRunAsConnection
    Add-AzureRMAccount -ServicePrincipal -Tenant $Auth.TenantID -ApplicationId $Auth.ApplicationID -CertificateThumbprint $Auth.CertificateThumbprint

    $params = @{"StorageAccountKey"="Test";"StorageAccountName"="Test";"JsonConfigLocation"="AzureDataFactoryControl/AzureDataFactoryControl.json"; "Action"="Pause"} 
    Start-AzureRmAutomationRunbook –AutomationAccountName "xxxAutomation" –Name "ChangePipelineStatus" -ResourceGroupName "xxx" –Parameters $params –wait

    I get the error 

    Start-AzureRmAutomationRunbook : Invalid runbook parameters.
    At line:11 char:1
    + Start-AzureRmAutomationRunbook –AutomationAccountName "xxxAutomation" ...

    I've tried various other methods with little success. For example embedding the child script in line which i normally do on Windows

    $LocalDir = Convert-Path .
    . "$LocalDir\ChangePipelineStatus.ps1";

    $joboutput = $(ChangePipelineStatus -StorageAccountKey "Test" -StorageAccountName "Test" -JsonConfigLocation "AzureDataFactoryControl/AzureDataFactoryControl.json" -Action "Pause")

    Here I get a different error::


    The term 'C:\Temp\qgtnlnt5.e5w\ChangePipelineStatus.ps1' is not recognized as the name of a cmdlet, function, 
    script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is 

    So my question is how can I create functions inside scripts and re-use these? I've searched and have not found a clear enough example resource online and perhaps if someone knows how will be happy to share. 

    Thank you for your help

    John

    Monday, July 3, 2017 9:59 PM

All replies

  • Hi Ilavelan

    Thank you for your help. I had some success using the methods in the above link. The only thing I'm stuck on is returning a value from the child cmdlet. For example

    $params = @{"StorageAccountKey"="Test";"StorageAccountName"="Test";"JsonConfigLocation"="AzureDataFactoryControl/AzureDataFactoryControl.json"; "Action"="Pause"} 

    $joboutput = Start-AzureRmAutomationRunbook –AutomationAccountName "xxxAutomation" –Name "ChangePipelineStatus" -ResourceGroupName "xxx" –Parameters $params 

    The child cmdlet (ChangePipelineStatus) is as follows

    Param(
        [string]$StorageAccountKey,
        [string]$StorageAccountName,
        [string]$JsonConfigLocation,
        [string]$Action
    )
    {
        return $Action
    }

    I know the above doesn't do anything :-) its just to demonstrate the issue

    Hence I would expect the above cmdlet to return the string "Pause" into a property of the variable $joboutput

    The objective of returning a value is to manage the outcome of running the cmdlet

    instead I get the following

    ResourceGroupName      : xxx
    AutomationAccountName  : xxxAutomation
    JobId                  : 2e472682-45c7-48ae-86a5-c0e1b20faffc
    CreationTime           : 7/19/2017 1:18:48 PM +00:00
    Status                 : New
    StatusDetails          : None
    StartTime              : 
    EndTime                : 
    Exception              : 
    LastModifiedTime       : 7/19/2017 1:18:48 PM +00:00
    LastStatusModifiedTime : 7/19/2017 1:18:48 PM +00:00
    JobParameters          : {StorageAccountName, JsonConfigLocation, StorageAccountKey, action}
    RunbookName            : ChangePipelineStatus
    HybridWorker           : 
    StartedBy              : 

    I've tried other methods for example using Get-AzureRmAutomationJob, with no success

    do {
        Write-verbose "Waiting for job to complete" -verbose
        Start-sleep -seconds 1
        $job = Get-AzureRmAutomationJob -Id $joboutput.JobId -AutomationAccountName "xxxAutomation" -ResourceGroupName "xxx"
    }
    until ($job.Status -eq "completed")

    $out = Get-AzureRmAutomationJobOutput -Id $joboutput.JobId -Stream output -AutomationAccountName "xxxAutomation" -ResourceGroupName "xxx" | Get-AzureRmAutomationJobOutputRecord
    write-output $out
    write-output $out.Value
    write-output $out.Value.StartPosition
    write-output $out.Value.Ast

    The question is how can i get the result of the return value from the child cmdlet?

    Without this there is no way of managing the outcome

    Thank you for your help

    Regards

    John

    Wednesday, July 19, 2017 1:29 PM
  • Please try the below cmdlet

    #Get Runbook output

    Get-AzureRmAutomationJobOutput -Id $jobid -Stream Output -ResourceGroupName $ResourceGroup -AutomationAccountName $AutomationAccountName -OutVariable JobOutput

    ($JobOutput |  Get-AzureRmAutomationJobOutputRecord | Select-Object -ExpandProperty Value).values -join "`n"

    Let us know if u have further questions.

    Wednesday, July 19, 2017 8:39 PM