来自 TFS 发布自动化的 IIS 管理 - PowerShell 脚本失败 Get-ChildItem -Path IIS:\Sites

IIS Administration from TFS Release automation - PowerShell script fails Get-ChildItem -Path IIS:\Sites

我在将 Powershell WebAdministration 模块与 Powershell 5.1 一起使用时遇到困难。

这是在 Server 2008R2 机器上,运行ning IIS 7.5

这个模块似乎有一个问题,偶尔模块在加载后需要几毫秒才能完成初始化。建议在加载后做一个简单的'write-output',让服务器完成初始化任务。我没有在我管理的所有服务器上看到它,但是这个特定的服务器在它的需要上是一致​​的。

还有一个问题,我发现人们遇到了 Get-Sites 失败的问题,可以通过包装在 try/catch.

中来解决

但是,我看到的问题是,即使使用已确定的解决方法,我也无法在交互式 运行 和从 TFS Automated 执行的 运行 之间获得一致的结果发布。

Import-Module WebAdministration
$sites="none"
Write-Output "suggested as a work around for the task dying for no apparent reason"
try {
    $sites = Get-ChildItem -Path IIS:\Sites
    Write-Output "part of try"
} catch {
    $sites = Get-ChildItem -Path IIS:\Sites
    Write-Output "part of catch"
} finally {
    Write-Output  $sites
    Write-Output  $sites.GetType()
}

当 运行 通过 TFS 发布自动化(代理版本 2.117.2,目标机器上的 PowerShell 版本 1.0.47)时:

 2018-01-25T13:18:29.5474995Z Importing alias 'End-WebCommitDelay'.
 2018-01-25T13:18:29.5474995Z 
 2018-01-25T13:18:29.5474995Z suggested as a work around for the task dying for no apparent reason
 2018-01-25T13:18:29.5474995Z part of catch
 2018-01-25T13:18:29.5474995Z 
 2018-01-25T13:18:29.5474995Z 
 2018-01-25T13:18:29.5631000Z Deployment status for machine 'DESTSERV:5985' : 'Passed'

(未 return 编辑站点列表)

当 运行 作为一个交互式进程时(与同一用户)

PS C:\Users\Install> C:\Installers\Modules\test-iis.ps1
suggested as a work around for the task dying for no apparent reason
part of try

Name             ID   State      Physical Path                  Bindings
----             --   -----      -------------                  --------
AppTest          2    Started    E:\WebApps\AppTest             http *:80:
                                                                https *:443:
Test             1    Stopped    C:\inetpub\wwwroot\Test        http *:80:
                                                                https 



Module                     : CommonLanguageRuntimeLibrary
Assembly                   : mscorlib, Version=4.0.0.0, Culture=neutral, 
PublicKeyToken=b77a5c561934e089
TypeHandle                 : System.RuntimeTypeHandle
DeclaringMethod            :
BaseType                   : System.Array
UnderlyingSystemType       : System.Object[]
FullName                   : System.Object[]
AssemblyQualifiedName      : System.Object[], mscorlib, Version=4.0.0.0, 
Culture=neutral,
                             PublicKeyToken=b77a5c561934e089
Namespace                  : System
GUID                       : 00000000-0000-0000-0000-000000000000
IsEnum                     : False
GenericParameterAttributes :
IsSecurityCritical         : False
IsSecuritySafeCritical     : False
IsSecurityTransparent      : True
IsGenericTypeDefinition    : False
IsGenericParameter         : False
GenericParameterPosition   :
IsGenericType              : False
IsConstructedGenericType   : False
ContainsGenericParameters  : False
StructLayoutAttribute      :
Name                       : Object[]
MemberType                 : TypeInfo
DeclaringType              :
ReflectedType              :
MetadataToken              : 33554432
GenericTypeParameters      : {}
DeclaredConstructors       : {Void .ctor(Int32)}
DeclaredEvents             : {}
DeclaredFields             : {}
DeclaredMembers            : {Void Set(Int32, System.Object), System.Object& 
Address(Int32), System.Object Get(Int32),
                             Void .ctor(Int32)}
DeclaredMethods            : {Void Set(Int32, System.Object), System.Object& 
Address(Int32), System.Object Get(Int32)}
DeclaredNestedTypes        : {}
DeclaredProperties         : {}
ImplementedInterfaces      : {System.ICloneable, System.Collections.IList, 
System.Collections.ICollection,
                             System.Collections.IEnumerable...}
TypeInitializer            :
IsNested                   : False
Attributes                 : AutoLayout, AnsiClass, Class, Public, Sealed, 
Serializable
IsVisible                  : True
IsNotPublic                : False
IsPublic                   : True
IsNestedPublic             : False
IsNestedPrivate            : False
IsNestedFamily             : False
IsNestedAssembly           : False
IsNestedFamANDAssem        : False
IsNestedFamORAssem         : False
IsAutoLayout               : True
IsLayoutSequential         : False
IsExplicitLayout           : False
IsClass                    : True
IsInterface                : False
IsValueType                : False
IsAbstract                 : False
IsSealed                   : True
IsSpecialName              : False
IsImport                   : False
IsSerializable             : True
IsAnsiClass                : True
IsUnicodeClass             : False
IsAutoClass                : False
IsArray                    : True
IsByRef                    : False
IsPointer                  : False
IsPrimitive                : False
IsCOMObject                : False
HasElementType             : True
IsContextful               : False
IsMarshalByRef             : False
GenericTypeArguments       : {}
CustomAttributes           : {[System.SerializableAttribute()]}


PS C:\Users\Install>

当 WebAdministration 没有正确导入时,似乎除了缓慢的初始化之外还有更多的错误。 IIS: provider is not functional.. 它不会抛出任何错误。不过它确实 return 做了一些事情 - 在脚本顶部设置的值正在被覆盖...我只是没有得到站点列表。

正如交互式 运行 所见,存在站点,因此空 return 值没有任何意义。

更新:

已应用所有建议的解决方法,但捕获中的 Get-ChildItem 无法生成站点列表。如何获得一致的结果,我可以在目标机器任务上以交互方式和通过 TFS Release 的 PowerShell 获取 IIS 中的完整站点列表?

我可以 运行 通过 TFS 发布自动化脚本而不会出现任何错误,并获得与交互过程一致的结果。 (代理版本 2.117.1,目标机器上的 PowerShell 版本 5.1.14393.1944)。

您需要将 TFS build agent service account 设置为目标计算机中的本地管理员帐户(只需将 build agent service account 添加到本地 administrators 组)。

所以,请尝试一下。如果还是不行,请尝试升级目标机器上的 PowerShell 版本(可能是 PS 版本引起的)。详见Install PowerShell 5 in Windows Server 2008 R2


更新:

通常,当 运行 具有任务 PowerShell on the target machines 的 PS 脚本时,脚本的输出不会返回到构建过程。

您需要更新脚本以取回输出(使用 Write-Verbose 而不是 Write-Output ),只需尝试以下脚本,它对我有用:

Import-Module WebAdministration
$sites="none"
Write-Verbose "suggested as a work around for the task dying for no apparent reason"
try {
    $sites = Get-ChildItem -Path IIS:\Sites | Out-String
    Write-Verbose "part of try"
} catch {
    $sites = Get-ChildItem -Path IIS:\Sites | Out-String
    Write-Verbose "part of catch"
} finally {
    Write-Verbose  $sites -verbose
    Write-Verbose  $sites.GetType() -verbose
}