在 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
- 在 运行book 服务器上我有所有合适的 Powershell 模块
安装。
- 已加入域。
- 它被添加为 DNSServer 上的可信主机,它也是一个域控制器
- 我想要 运行 这个上下文中的用户是 MYDOMAIN\asrscripts,它被添加为 Azure Automation Credential 工件
- 如果我尝试将 Hybrid Worker 的 RUNAS 用户更改为 CUSTOM 并选择我的 asrscripts 工件,作业会挂起,并且永远不会 运行s。它会一直保持在 Queued 状态,直到它挂起。我在系统事件日志中收到用户无法验证的错误。
- 我已经用完了下面的远程故障排除文档
希望有人能提供帮助。
谢谢!
"Cannot find the '-PSComputerName' command"提示代码格式不正确导致语法错误。 PowerShell 无法将其解释为参数,它认为这是一个单独的命令。你能展示一下你是如何将这个参数准确地应用到 InlineScript 的吗?例如,如果您这样做,您将收到此错误:
InlineScript {
...
}
-PSComputerName MyComputer
相反,您需要这样做:
InlineScript {
...
} -PSComputerName MyComputer
或:
InlineScript {
...
} `
-PSComputerName MyComputer
我有一本 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
- 在 运行book 服务器上我有所有合适的 Powershell 模块 安装。
- 已加入域。
- 它被添加为 DNSServer 上的可信主机,它也是一个域控制器
- 我想要 运行 这个上下文中的用户是 MYDOMAIN\asrscripts,它被添加为 Azure Automation Credential 工件
- 如果我尝试将 Hybrid Worker 的 RUNAS 用户更改为 CUSTOM 并选择我的 asrscripts 工件,作业会挂起,并且永远不会 运行s。它会一直保持在 Queued 状态,直到它挂起。我在系统事件日志中收到用户无法验证的错误。
- 我已经用完了下面的远程故障排除文档
希望有人能提供帮助。 谢谢!
"Cannot find the '-PSComputerName' command"提示代码格式不正确导致语法错误。 PowerShell 无法将其解释为参数,它认为这是一个单独的命令。你能展示一下你是如何将这个参数准确地应用到 InlineScript 的吗?例如,如果您这样做,您将收到此错误:
InlineScript {
...
}
-PSComputerName MyComputer
相反,您需要这样做:
InlineScript {
...
} -PSComputerName MyComputer
或:
InlineScript {
...
} `
-PSComputerName MyComputer