gpt4 book ai didi

具有名称属性的 Powershell New-WebBinding 管道问题

转载 作者:行者123 更新时间:2023-12-03 16:35:51 35 4
gpt4 key购买 nike

在对象中进行管道传输时,我遇到了 New-WebBinding 的问题。我有一个定义 5 个属性的对象:名称、协议(protocol)、端口、IPAddress 和 HostHeader(New-WebBinding cmdlet 支持所有 5 个属性作为接受管道输入:ValueByPropertyName)。然而,当你在这个对象中使用管道时,它仍然请求一个 Name: 被提交。如果您想复制问题,这里有一个快速测试功能。如果您在提示符下按 Enter,它会成功处理对象,并添加绑定(bind)。但是提示本身将其破坏为非交互式脚本。

我已经用 PS v3 和 PS v4 对此进行了测试。

我很确定我做这一切都是正确的,但想确保没有我可能忽略的东西。现在我只是在没有这个问题的 foreach 循环中遍历我的对象集合,但想看看这是否是我应该报告的错误。

function Test-WebBinding{
[CmdletBinding()]
Param()

$testBindingCol = @()

$testBinding1 = New-Object System.Object
$testBinding1 | Add-Member -MemberType NoteProperty -Name Name -Value 'Default Web Site'
$testBinding1 | Add-Member -MemberType NoteProperty -Name Protocol -Value 'https'
$testBinding1 | Add-Member -MemberType NoteProperty -Name Port -Value '4000'
$testBinding1 | Add-Member -MemberType NoteProperty -Name IPAddress -Value '*'
$testBinding1 | Add-Member -MemberType NoteProperty -Name HostHeader -Value 'Test4000'
$testBindingCol += $testBinding1

$testBinding2 = New-Object System.Object
$testBinding2 | Add-Member -MemberType NoteProperty -Name Name -Value 'Default Web Site'
$testBinding2 | Add-Member -MemberType NoteProperty -Name Protocol -Value 'http'
$testBinding2 | Add-Member -MemberType NoteProperty -Name Port -Value '4001'
$testBinding2 | Add-Member -MemberType NoteProperty -Name IPAddress -Value '*'
$testBinding2 | Add-Member -MemberType NoteProperty -Name HostHeader -Value 'Test4001'
$testBindingCol += $testBinding2

$testBindingCol | New-WebBinding
}

最佳答案

PetSerAl 在上面的评论中提出了正确的想法:

One workaround would be to change current location to some site (cd IIS:\Sites\SomeSite), it does not really matter to which



这确实有效,但为什么它在正常的文件系统提示下不起作用?

找出原因 New-WebBinding我加载了 Microsoft.IIS.PowerShell.Provider 的行为方式包含此内容和其他内容的程序集 WebAdministration cmdlet 进入 dotPeek。程序集位于 GAC 中,因此您告诉 dotPeek“从 GAC 打开”。

加载后,我们感兴趣的类被称为 NewWebBindingCommand .

粗略检查后,我们可以看到所有参数属性都用 [Parameter(ValueFromPipelineByPropertyName = true)] 修饰。属性,所以这是一个好的开始,管 Prop 有匹配属性名称的对象数组应该可以工作:

enter image description here
NewWebBindingCommand最终继承自 System.Management.Automation.Cmdlet 并且在这种情况下覆盖了 BeginProcessing 方法。如果被覆盖, BeginProcessing由 PowerShell 调用并“为 cmdlet 提供一次性预处理功能”。

了解 cmdlet 的 BeginProcessing 很重要。在处理任何管道馈送的命名参数并将其绑定(bind)到 cmdlet 的属性之前调用 override (请参阅: Cmdlet Processing Lifecycle (MSDN) )。

我们的 New-WebBinding BeginProcessing cmdlet 的实现好像:
protected override void BeginProcessing()
{
base.BeginProcessing();
if (!string.IsNullOrEmpty(this.siteName))
return;
this.siteName = this.GetSiteName("Name");
}
this.siteNameName 的私有(private)成员值将绑定(bind)到 -Name 的属性范围。当我们到达 if(...) `this.siteName 上面的语句还没有绑定(bind)(它是空的),因此落入:
this.siteName = this.GetSiteName("Name");

调用 GetSiteName()调用 cmdlet 的直接基类 HelperCommand它提供了许多对许多不同的有用的“帮助”方法 WebAdministration cmdlet。
HelperCommand.GetSiteName(string prompt)看起来像这样:
protected string GetSiteName(string prompt)
{
PathInfo pathInfo = this.SessionState.PSVariable.Get("PWD").Value as PathInfo;
if (pathInfo != null && pathInfo.Provider.Name.Equals("WebAdministration", StringComparison.OrdinalIgnoreCase))
{
string[] strArray = pathInfo.Path.Split('\\');
if (strArray.Length == 3 && strArray[1].Equals("sites", StringComparison.OrdinalIgnoreCase))
return strArray[2];
}
if (!string.IsNullOrEmpty(prompt))
return this.PromptForParameter<string>(prompt);
return (string) null;
}

为了了解这个问题,我创建了自己的 PowerShell cmdlet(称为 Kevulator,抱歉)并拉入了 New-WebBinding cmdlet 的 BeginProcessing()代码和来自 New-WebBinding 的代码的基类辅助方法 GetSiteName() .

这是闯入的截图 GetSiteName在 VS2015 中,当附加到绑定(bind)到 New-Kevulator 的 PowerShell session 管道时:

enter image description here

顶部箭头表明我们的 NamesiteName 支持的属性(property)还没有绑定(bind),还在 null (如上所述导致 GetSiteName 被执行)。我们也刚刚越过这条线上的一个断点:
PathInfo pathInfo = 
this.SessionState.PSVariable.Get("PWD").Value as PathInfo;

...这决定了我们所处的路径提供者类型。在这种情况下,我们使用的是普通文件系统 C:\>提示,因此提供者名称将为 FileSystem .我用第二个箭头突出显示了这一点。

如果我们 Import-Module WebAdministrationCD IIS:然后重新运行并再次中断您可以看到路径提供程序已更改为 WebAdministration负责处理里面的生命 IIS:>超越:

enter image description here

如果 pathInfo名称不等于 WebAdministration ,即我们不在 IIS:提示,然后代码失败并提示 Name命令行中的参数,就像您所经历的那样。

如果 pathInfo值为 WebAdministration然后会发生两件事之一:

如果路径是 IIS:IIS:\Sites代码失败并提示 Name范围。

如果路径是 IIS:\Sites\SomeSiteName然后 SomeSiteName返回并有效地变为 -Name参数值,我们从 GetSiteName() 中退出功能返回 BeginProcessing .

最后一个行为很有用,因为如果您当前的路径是 IIS:\Sites\MySite然后你可以输入该站点的绑定(bind)数组,但不指定 Name范围。或者,如果您确实提供了 Name对象的管道数组中的属性,那么这些将覆盖从您的 IIS:\Sites\MySite 中选取的默认站点名称。语境。

所以,回到我们的代码,一次 BeginProcessing已经运行我们的管道命名参数现在实际上已绑定(bind),然后是 ProcessRecord方法被调用,这就是 New-WebBinding的肉和土 bean 工作必须执行。

TLDR:
New-WebBinding除非您将当前工作目录更改为 IIS 网站,否则不会绑定(bind)管道参数,例如 cd iis:\Sites\MySite .

关于具有名称属性的 Powershell New-WebBinding 管道问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35419625/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com