执行 powershell 时 Kudu REST API 命令端点错误

Kudu REST API Command endpoint error when executing powershell

当试图根据this description执行POST到/api/command时出现以下错误:

PS C:\> $Result.Error
remove-item : The Win32 internal error "The handle is invalid" 0x6 occurred 
while getting the console mode. Contact Microsoft Customer Support Services.
At line:1 char:44
+ get-childitem * -recurse | remove-item -force
+                                            ~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (:) [Remove-Item], HostExce 
   ption
    + FullyQualifiedErrorId : GetConsoleMode,Microsoft.PowerShell.Commands.Rem 
   oveItemCommand

我用来执行此操作的 POSH 脚本片段:

$json = @"
{
    "command": 'powershell.exe -command `"get-childitem * -recurse | remove-item -force`"',
    "dir" : 'site\wwwroot',
 }
"@

$kuduApiUrl = "https://$webAppName.scm.azurewebsites.net/api/command"

$progressPreference = "silentlyContinue"

$Result = Invoke-RestMethod -Uri $kuduApiUrl `
                        -Headers @{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} `
                        -Body $json `
                        -Method POST `
                        -ContentType "application/json"

我发现很多博客都指出这与交互式控制台输出有关,但是,将 $ProgressPreference 设置为 SilentlyContinue 并没有多大帮助。

我无法反驳你提到的问题。我用下面的代码测试,你可以参考一下。

$PublishingUsername = "`$userName"

$publishingPassword = "password"

$apiUrl = "https://webAppName.scm.azurewebsites.net/api/command"

$json = @"
{
    "command": 'powershell.exe -command `"get-childitem * -recurse | remove-item -force`"',
    "dir" : 'site\wwwroot'
 }
"@

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $PublishingUsername, $publishingPassword)))

$Result = Invoke-RestMethod -Uri $apiUrl -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}  -Method Post -Body $json -ContentType "application/json"

测试结果: 我还查看了kudu控制台,文件夹site\wwwroot下的所有项目都被删除了。

github 上检查了这个问题后,正确的 POSH 命令应该是:

get-childitem -recurse | remove-item -recurse -force

直接从 Kudu 控制台甚至 REST 执行时效果很好 API /api/command 端点

如果已接受的答案不适合您的情况(即您不想在调用 Remove-Item 时使用 -Recurse,因为那样会破坏您想要从中排除的项目删除,当其包含的文件夹被递归删除时),以下对我有用:

Get-ChildItem d:\mypath -Recurse -Exclude FileToExclude.ext | Select -ExpandProperty FullName | sort length -Descending | foreach { Remove-Item -Path "$_" -Force }

由于 this bug,似乎简单地将文件对象通过管道传递给 Remove-Item 是行不通的,但是通过管道传递完整的文件名,然后将其用作 -Path 参数,可以绕过它。