在 PowerShell 工作流中正确使用 <Activity Common Parameters> for Inlinescript

Proper use of <Activity Common Parameters> for Inlinescript in PowerShell Workflow

我有一本 Azure Automation Powershell Workflow 运行book,我希望 运行 在混合 运行book Worker 服务器上,作为 Azure Site Recovery 故障转移的一部分 post-动作步骤。

在高层,运行这本书利用 Azure 运行 AS 连接来收集将被故障转移的虚拟机之一的私有 IP 地址。存储此 IP 地址,然后将其写入环境中配置的 Active Directory DNS 中的 STATIC A 记录。

> NOTE I promise you there's a good reason we're doing this. I realize that the machine itself as it comes up on AD will refresh it's personal DNS name entry, this is a separate A record, that we want to point to the IP address of the failed over server. We aren't using CNAME because of a defined issue with the application this server hosts.

所以我必须更新这条A记录。您将在下面找到执行此操作的脚本。当我使用适当的凭据 (mydomain\asrscripts).mydomain\asrscripts.

在混合 运行book 服务器上登录服务器时,下面的脚本可以正常工作。
workflow VisionWebFailover-Test

{

inlineScript {

    $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
        }
    }

    $rg = "RG03ASR" #ResoureGroup where ASR Machines will come up
    $vmName = "ASRJUMP01" #VMname of the VM I need to get the IP from for updating in DNS



    Write-output "Getting IP"

    $ip = (Get-AzureRmNetworkInterface | Where-Object {($_.VirtualMachine.id).Split("/")[-1] -like $vmname}).IpConfigurations.PrivateIpAddress #find the primary nic and store it's IP address

    Write-Output "Returned VM IP"
    Write-Output $ip


        #PowerShell to be executed locally
        Import-Module dnsserver
        $hostname = 'customArecord'
        $zonname = 'mydomain.com'
        $DNSServer = 'MYDNSServer.mydomain.com'

        #Grab the existing DNS record and store it in the variable $oldobj
        $oldobj = Get-DnsServerResourceRecord -Name $hostname -ZoneName $zonname -RRType A -ComputerName $DNSServer
        Write-Output $oldobj

        #Copy the DNS record into $newobj
        $newobj = $oldobj.Clone()

        #Change the value of the IP address in $newobj to equal the IP address assigned to the visionwebdev server in Azure
        [System.Net.IPAddress]$NewIP = [System.Net.IPAddress]($ip)
        $newobj.RecordData.IPv4Address = $NewIp

        Write-Output $NewIP "this is the new IP that will be updated to DNS"

        write-output $newobj
        #Here is where we actually apply the change to the DNS record

        Set-DnsServerResourceRecord -ZoneName $zonname -OldInputObject $oldobj -NewInputObject $newobj -Computername $DNSServer -passthru

        Write-Output "DNS entry updated, replication may take 15 minutes"
    }

上述代码中的每一步都成功进行,直到它到达 Set-DNSServerResourceRecord 语句,并失败并出现如下所示的权限被拒绝错误。这是我 运行 来自 Azure 自动化门户的作业。当我 运行 它在以用户身份登录的本地框上正常工作时。

Set-DnsServerResourceRecord : Failed to update record customArecord.mydomain.com.
At VisionWebFailover-Test:27 char:27
+ 
   + CategoryInfo : PermissionDenied:(customArecord.mydomain.com:root/Microsoft/...rResourceRecord) 
[Set-DnsServerResourceRecord], CimException
    + FullyQualifiedErrorId : WIN32 5,Set-DnsServerResourceRecord

> I'm thinking I need to use at the end of my InlineScript block to force the code to execute against the DNS server in the defined user context that I want. Although what I really want is for the commands to execute ON the hybrid runbook worker in the defined user context.

about_inlinescript 文档说它接受 https://docs.microsoft.com/en-us/powershell/module/psworkflow/about/about_inlinescript?view=powershell-5.1

并为我提供了一个这样的例子

InlineScript {<script block>} <ActivityCommonParameters>

Activity 通用参数 由本文档定义 https://docs.microsoft.com/en-us/powershell/module/psworkflow/about/about_activitycommonparameters?view=powershell-5.1

它引用了我希望使用的两个参数 -PSComputerName-PSCredential

我像这样构建一个凭证对象

$secpasswd = ConvertTo-SecureString "MyAwesomePassword" -AsPlainText -Force $mycreds = New-Object System.Management.Automation.PSCredential ("MYDOMAIN\asrscripts", $secpasswd)

我什至使用

从 Automation 中提取了资产

$domainCred = Get-AutomationPSCredential -Name 'asrscripts'

当我 运行 我的代码并尝试通过将 -PSComputername 或 -PSCredential 添加到 InlineScript 的末尾来模仿示例时,我得到了错误。

At line:94 char:7 + -PSComputerName 'MYDNSServer' -PSCredential $domainCred + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Cannot find the '-PSComputerName' command. If this command is defined as a workflow, ensure it is defined before the workflow that calls it. If it is a command intended to run directly within Windows PowerShell (or is not available on this system), place it in an InlineScript: 'InlineScript { -PSComputerName }'

如果我按照上述错误的建议并将 -PSComputerName 和 -PSCredential 放在 InlineScript 块中,我会收到一个错误,它找不到 -PSComputerName 和 -PSCredential[=26= 的 Set-DNSServerResourceRecord 的参数]

> I don't know what I'm doing wrong

关于远程故障排除 - https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_troubleshooting?view=powershell-5.1

希望有人能提供帮助。 谢谢!

"Cannot find the '-PSComputerName' command"提示代码格式不正确导致语法错误。 PowerShell 无法将其解释为参数,它认为这是一个单独的命令。你能展示一下你是如何将这个参数准确地应用到 InlineScript 的吗?例如,如果您这样做,您将收到此错误:

InlineScript {
    ...
}
-PSComputerName MyComputer

相反,您需要这样做:

InlineScript {
    ...
} -PSComputerName MyComputer

或:

InlineScript {
    ...
} `
-PSComputerName MyComputer