为何PowerShell脚本手动正常,CodeDeploy执行报80040154类未注册错误?
问题原因
这个错误的核心原因是CodeDeploy Agent在Windows上默认以32位进程运行,而你用来管理IIS的WebAdministration模块依赖的COM组件是64位的。32位PowerShell环境无法找到这些64位注册的组件,所以抛出80040154 Class not registered错误。
手动运行脚本正常是因为你通常打开的是64位PowerShell(默认情况下,Windows的PowerShell快捷方式是64位版本),它能正确加载IIS管理所需的COM组件。
解决方案
有两种常用的解决方式:
方式一:在appspec.yml中指定64位PowerShell路径
修改appspec.yml的AfterInstall钩子,明确指定使用64位PowerShell来执行脚本:
version: 0.0 os: windows files: - source: / destination: C:\connect\MicroServices\authentication overwrite: true file_exists_behavior: OVERWRITE hooks: AfterInstall: - location: automation-script1.ps1 timeout: 3000 runas: Administrator interpreter: "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe是64位PowerShell的路径,CodeDeploy会用这个解释器来执行你的脚本,确保能加载64位的IIS COM组件。
方式二:在PowerShell脚本中强制切换到64位环境
在你的automation-script1.ps1开头添加以下代码,检测当前PowerShell位数,如果是32位,自动重启64位PowerShell并重新运行脚本:
# 检测是否为32位PowerShell,若是则切换到64位 if ($env:PROCESSOR_ARCHITEW6432 -eq "AMD64") { if ($myInvocation.Line) { & "$env:WINDIR\SysNative\WindowsPowerShell\v1.0\powershell.exe" -NonInteractive -NoProfile $myInvocation.Line } else { & "$env:WINDIR\SysNative\WindowsPowerShell\v1.0\powershell.exe" -NonInteractive -NoProfile -File "$($myInvocation.InvocationName)" $args } exit $LASTEXITCODE } # 原脚本内容从这里开始 # Define parameters $siteName = "test1" $physicalPath = "C:\connect\MicroServices\authentication" $applicationPool = "testPool" $dnsName = "devteam5.localhost" # Check if the application pool exists $AppPoolExists = Get-WebAppPoolState -Name $applicationPool -ErrorAction SilentlyContinue if (-not $AppPoolExists) { Write-Host "Application Pool '$applicationPool' does not exist. Creating..." New-WebAppPool -Name $applicationPool Write-Host "Application Pool '$applicationPool' created successfully." } # Check if the site already exists $siteExists = Get-Website -Name $siteName -ErrorAction SilentlyContinue if ($siteExists) { Write-Host "The website '$siteName' already exists in IIS. Script stopped." exit } # If site doesn't exist, create it with the DNS binding New-WebSite -Name $siteName -PhysicalPath $physicalPath -ApplicationPool $applicationPool -HostHeader $dnsName -Port 80 -Force Write-Host "Website '$siteName' created successfully in IIS and bound to '$dnsName'."
这段代码会自动检测并切换到64位环境,确保脚本能正确调用IIS的管理Cmdlets。
内容的提问来源于stack exchange,提问作者Rehan CH
相关产品推荐
相关产品推荐

