0

我有一个 Azure 自动化 Powershell 工作流 Runbook,我希望在 Hybrid Runbook Worker 服务器上运行它,作为 Azure Site Recovery 故障转移后操作步骤的一部分。

在较高级别上,Runbook 使用 Azure Run AS 连接来收集将进行故障转移的 VM 之一的专用 IP 地址。存储此 IP 地址,然后将其写入环境中配置的 Active Directory DNS 中的 STATIC A 记录。

> 注意我向您保证,我们这样做是有充分理由的。我意识到机器本身在 AD 上出现时会刷新它的个人 DNS 名称条目,这是一个单独的 A 记录,我们要指向故障转移服务器的 IP 地址。由于此服务器托管的应用程序存在已定义问题,我们没有使用 CNAME。

所以我必须更新这条A记录。您将在下面找到执行此操作的脚本。当我使用适当的凭据 (mydomain\asrscripts) 登录到服务器时,当我在 Hybrid Runbook Server 上运行它时,下面的这个脚本可以正常工作。

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 语句,并失败并出现如下所示的 Permission Denied Error。这是我从 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

> 我想我需要在我的 InlineScript 块的末尾使用来强制代码在我想要的已定义用户上下文中针对 DNS 服务器执行。尽管我真正想要的是在定义的用户上下文中在混合 Runbook 工作人员上执行命令。

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

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

InlineScript {<script block>} <ActivityCommonParameters>

活动通用参数由本文档定义 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)

我什至使用自动化从自动化中提取了资产

$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 块内,我会收到一个错误,它无法找到 Set-DNSServerResourceRecord 的参数,用于 -PSComputerName 和 -PSCredential

> 我不知道我做错了什么

  • 在 Runbook 服务器上,我安装了所有适当的 Powershell 模块。
  • 它已加入域。
  • 它被添加为 DNSServer 上的受信任主机,它也是域控制器
  • 我想在 MYDOMAIN\asrscripts 的上下文中运行它的用户,它被添加为 Azure 自动化凭据工件
  • 如果我尝试将 Hybrid Worker 的 RUNAS 用户更改为 CUSTOM 并选择我的 asrscripts 工件,则作业会挂起,并且永远不会运行。它一直处于 Queued 状态,直到挂起。我在系统事件日志中收到用户无法验证的错误。
  • 我已经用尽了下面的远程故障排除文档

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

希望有人可以提供帮助。谢谢!

4

1 回答 1

1

“找不到 '-PSComputerName' 命令”表示由不正确的代码格式导致的语法错误。PowerShell 在将其解释为参数时遇到了麻烦,它认为这是一个单独的命令。您能否说明如何将此参数准确应用于 InlineScript?例如,如果您这样做,您将收到此错误:

InlineScript {
    ...
}
-PSComputerName MyComputer

相反,您需要执行以下操作:

InlineScript {
    ...
} -PSComputerName MyComputer

或者:

InlineScript {
    ...
} `
-PSComputerName MyComputer
于 2018-02-09T18:21:50.310 回答