我有一个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 worker执行。
about_inlinescript 文档说它接受了 https://docs.microsoft.com/en-us/powershell/module/psworkflow/about/about_inlinescript?view=powershell-5.1
并提供了一个像这样的例子
InlineScript {<script block>} <ActivityCommonParameters>
活动常用参数由此doc定义 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'
当我运行我的代码并尝试模仿该示例时,通过在InlineScript的末尾添加-PSComputername或-PSCredential,我会收到错误。
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 INSIDE放在InlineScript块中,我会收到一个错误,它无法找到-PSComputerName和-PSCredential的Set-DNSServerResourceRecord的参数
&GT; 我不知道我做错了什么
希望有人可以提供帮助。 谢谢!
答案 0 :(得分:1)
&#34;无法找到&#39; -PSComputerName&#39;命令&#34;建议由错误的代码格式化导致语法错误。 PowerShell将此解释为参数时遇到麻烦,它认为这是一个单独的命令。您能否详细说明如何将此参数应用于InlineScript?例如,如果您执行此操作,则会出现此错误:
InlineScript {
...
}
-PSComputerName MyComputer
相反,你需要这样做:
InlineScript {
...
} -PSComputerName MyComputer
或:
InlineScript {
...
} `
-PSComputerName MyComputer