在 DSC 脚本中添加入站重写规则不起作用
Adding Inbound Rewrite Rule in DSC script does not work
正如标题所说,我正在为反向代理功能配置重写规则:
- IIS 8.5
- Windows 服务器 2012R2
- URL 重写 2.1
- 应用程序请求路由 3.0
- Powershell 5.1
为此,我使用 Powershell DSC,在脚本资源中设置配置。这对于出站规则非常有效,但入站规则没有创建,也没有给出 error/warning。
当试图在其上设置属性时(在后面的 3 行),会显示一条警告说它找不到入站规则,顺便说一句,还显示了正确使用的变量名)。在 IIS 管理控制台中,它也不可见(是的,我在上面使用了 F5)。
我正在使用 IIS 本身生成的命令,它与我在网上看到的所有内容相同,包括 Whosebug。这个特殊问题不容易找到,所以我一定遗漏了一些非常微不足道的东西。
我已经试过了:
- 运行不同凭证下的脚本
- 使用硬编码名称而不是变量
- 使用 URL 重写 2.0
- 正在重新启动 IIS
- 正在重启服务器
我让命令正常工作的唯一方法是在(提升的)Powershell(下面用 >>>> 标记)中将其作为单个命令执行。
然后是脚本本身。 (作为参考,也添加了一条出站规则):
SetScript = {
Write-Verbose "Checking if inbound rewrite rule is present..."
$inbound = (Get-WebConfiguration -Filter "//System.webServer/rewrite/rules" -PSPath "IIS:\Sites$using:frontendSiteName").Collection | Where-Object {$_.Name -eq "$using:inboundRuleName"}
if($inbound -eq $null) {
Write-Verbose "Inbound rewrite rule not present, configuring..."
>>>> Add-WebConfigurationProperty -Filter "//System.webServer/rewrite/rules" -Name "." -Value @{name=$using:inboundRuleName;stopProcessing="True"} -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/rules/rule[@name='$using:inboundRuleName']/match" -Name "url" -Value "^api/(.*)" -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/rules/rule[@name='$using:inboundRuleName']/action" -Name "type" -Value "Rewrite" -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/rules/rule[@name='$using:inboundRuleName']/action" -Name "url" -Value "http://localhost:8000/api/{R:1}" -PSPath "IIS:\Sites$using:frontendSiteName"
Write-Verbose "Inbound rewrite rule configured"
}
Write-Verbose "Checking if outbound HTML rule is present..."
$outboundHTML = (Get-WebConfiguration -Filter "//System.webServer/rewrite/outboundRules" -PSPath "IIS:\Sites$using:frontendSiteName").Collection | Where-Object {$_.Name -eq "$using:outboundHTMLRuleName"}
if($outboundHTML -eq $null) {
Write-Verbose "Outbound HTML rule not present, configuring..."
Add-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/preConditions" -Name "." -Value @{name='IsHTML'} -PSPath "IIS:\Sites$using:frontendSiteName"
Add-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/preConditions/preCondition[@name='IsHTML']" -Name "." -Value @{input='{RESPONSE_CONTENT_TYPE}';pattern='^text/html'} -PSPath "IIS:\Sites$using:frontendSiteName"
Add-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules" -Name "." -Value @{name=$using:outboundHTMLRuleName;preCondition='IsHTML'} -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/rule[@name='$using:outboundHTMLRuleName']/match" -Name "filterByTags" -Value "A" -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/rule[@name='$using:outboundHTMLRuleName']/match" -Name "pattern" -Value "^/(.*)" -PSPath "IIS:\Sites$using:frontendSiteName"
Add-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/rule[@name='$using:outboundHTMLRuleName']/conditions" -Name "." -Value @{input='{URL}';pattern='^/api/.*'} -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/rule[@name='$using:outboundHTMLRuleName']/action" -Name "type" -Value "Rewrite" -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/rule[@name='$using:outboundHTMLRuleName']/action" -Name "value" -Value "/{C:1}/{R:1}" -PSPath "IIS:\Sites$using:frontendSiteName"
Write-Verbose "Outbound HTML rewrite rule configured"
}
}
我希望有人知道为什么会这样,因为我在尝试解决这个问题时感到非常沮丧。
好吧,在尝试了更多之后(比如使用较新的 xScript 资源而不是 Script 并尝试将那 1 个失败的命令放入 Invoke-Command Scriptblock 中)我找到了解决方案。
解决方案: 在 Powershell 中,或者至少对于 IIS 配置,有两种方法可以将位置传递给命令。最广为人知的是 -PSPath,但还有 -Location。
当单独执行命令(以及其他命令)时,简单的工作是将 -PSPath "IIS:\Sites\SITENAME"
传递给命令。
我现在如何让它在我的脚本中为该命令工作是:-PSPath "IIS:\Sites" -Location "SITENAME"
.
我需要使用此解决方法的事实在我看来是 Powershell 到 IIS 转换(或仅重写模块)中的错误。如果我错了,请纠正我!
不管怎样,我的问题已经解决了,我希望这个答案能在以后帮助其他人解决这个问题。
感谢那些看过我的问题并思考过的人 :)
正如标题所说,我正在为反向代理功能配置重写规则:
- IIS 8.5
- Windows 服务器 2012R2
- URL 重写 2.1
- 应用程序请求路由 3.0
- Powershell 5.1
为此,我使用 Powershell DSC,在脚本资源中设置配置。这对于出站规则非常有效,但入站规则没有创建,也没有给出 error/warning。 当试图在其上设置属性时(在后面的 3 行),会显示一条警告说它找不到入站规则,顺便说一句,还显示了正确使用的变量名)。在 IIS 管理控制台中,它也不可见(是的,我在上面使用了 F5)。
我正在使用 IIS 本身生成的命令,它与我在网上看到的所有内容相同,包括 Whosebug。这个特殊问题不容易找到,所以我一定遗漏了一些非常微不足道的东西。 我已经试过了:
- 运行不同凭证下的脚本
- 使用硬编码名称而不是变量
- 使用 URL 重写 2.0
- 正在重新启动 IIS
- 正在重启服务器
我让命令正常工作的唯一方法是在(提升的)Powershell(下面用 >>>> 标记)中将其作为单个命令执行。
然后是脚本本身。 (作为参考,也添加了一条出站规则):
SetScript = {
Write-Verbose "Checking if inbound rewrite rule is present..."
$inbound = (Get-WebConfiguration -Filter "//System.webServer/rewrite/rules" -PSPath "IIS:\Sites$using:frontendSiteName").Collection | Where-Object {$_.Name -eq "$using:inboundRuleName"}
if($inbound -eq $null) {
Write-Verbose "Inbound rewrite rule not present, configuring..."
>>>> Add-WebConfigurationProperty -Filter "//System.webServer/rewrite/rules" -Name "." -Value @{name=$using:inboundRuleName;stopProcessing="True"} -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/rules/rule[@name='$using:inboundRuleName']/match" -Name "url" -Value "^api/(.*)" -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/rules/rule[@name='$using:inboundRuleName']/action" -Name "type" -Value "Rewrite" -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/rules/rule[@name='$using:inboundRuleName']/action" -Name "url" -Value "http://localhost:8000/api/{R:1}" -PSPath "IIS:\Sites$using:frontendSiteName"
Write-Verbose "Inbound rewrite rule configured"
}
Write-Verbose "Checking if outbound HTML rule is present..."
$outboundHTML = (Get-WebConfiguration -Filter "//System.webServer/rewrite/outboundRules" -PSPath "IIS:\Sites$using:frontendSiteName").Collection | Where-Object {$_.Name -eq "$using:outboundHTMLRuleName"}
if($outboundHTML -eq $null) {
Write-Verbose "Outbound HTML rule not present, configuring..."
Add-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/preConditions" -Name "." -Value @{name='IsHTML'} -PSPath "IIS:\Sites$using:frontendSiteName"
Add-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/preConditions/preCondition[@name='IsHTML']" -Name "." -Value @{input='{RESPONSE_CONTENT_TYPE}';pattern='^text/html'} -PSPath "IIS:\Sites$using:frontendSiteName"
Add-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules" -Name "." -Value @{name=$using:outboundHTMLRuleName;preCondition='IsHTML'} -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/rule[@name='$using:outboundHTMLRuleName']/match" -Name "filterByTags" -Value "A" -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/rule[@name='$using:outboundHTMLRuleName']/match" -Name "pattern" -Value "^/(.*)" -PSPath "IIS:\Sites$using:frontendSiteName"
Add-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/rule[@name='$using:outboundHTMLRuleName']/conditions" -Name "." -Value @{input='{URL}';pattern='^/api/.*'} -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/rule[@name='$using:outboundHTMLRuleName']/action" -Name "type" -Value "Rewrite" -PSPath "IIS:\Sites$using:frontendSiteName"
Set-WebConfigurationProperty -Filter "//System.webServer/rewrite/outboundRules/rule[@name='$using:outboundHTMLRuleName']/action" -Name "value" -Value "/{C:1}/{R:1}" -PSPath "IIS:\Sites$using:frontendSiteName"
Write-Verbose "Outbound HTML rewrite rule configured"
}
}
我希望有人知道为什么会这样,因为我在尝试解决这个问题时感到非常沮丧。
好吧,在尝试了更多之后(比如使用较新的 xScript 资源而不是 Script 并尝试将那 1 个失败的命令放入 Invoke-Command Scriptblock 中)我找到了解决方案。
解决方案: 在 Powershell 中,或者至少对于 IIS 配置,有两种方法可以将位置传递给命令。最广为人知的是 -PSPath,但还有 -Location。
当单独执行命令(以及其他命令)时,简单的工作是将 -PSPath "IIS:\Sites\SITENAME"
传递给命令。
我现在如何让它在我的脚本中为该命令工作是:-PSPath "IIS:\Sites" -Location "SITENAME"
.
我需要使用此解决方法的事实在我看来是 Powershell 到 IIS 转换(或仅重写模块)中的错误。如果我错了,请纠正我! 不管怎样,我的问题已经解决了,我希望这个答案能在以后帮助其他人解决这个问题。 感谢那些看过我的问题并思考过的人 :)