Pregunta

%WINDIR%\system32\inetsrv\appcmd.exe set site /site.name:"WebRole_IN_0_CB" /[Path='/'].applicationPool:"ASP.NET v4.0" >>CBLog.log
powershell.exe -command Set-ExecutionPolicy Unrestricted
powershell.exe .\CheckIfSuccessful.ps1

Me gustaría ejecutar el script anterior y si appcmd.exe no puede ejecutarlo debido a que el sitio web aún no está listo y listo, recibiría el siguiente mensaje de error en el archivo cblog.log.

Error (mensaje: No se puede encontrar el objeto del sitio con el identificador "WebRole_in_0_cb".)

En checkifsuccessful.ps1 me gustaría crear un script PowerShell para bucle, que ejecuta el comando APPCMD y verifica el error nuevamente. Luego duerme durante 5 segundos y luego vuelve a reemplazar, hasta que tenga éxito.

¿Cómo haría esto en PowerShell?

altamente apreciado,

ACTUALIZAR:

Ok, muchas gracias por el consejo con $ LastExitCode, mientras que parece prometedor. Parece que tengo problemas para convertir quoates individuales en PowerShell: (el siguiente es parte de mi comando inicial APPCMD)

/[Path='/'].applicationPool:"ASP.NET v4.0"

¿Cómo cito esto en PowerShell? Traté de simplificarlo para que PowerShell tenga menos problemas con él, pero parece que mi comando ahora está mal, como dice ahora:

Error (mensaje: no puede encontrar el objeto del sitio con el identificador "v4.0".)

 & $Env:WinDir\system32\inetsrv\appcmd.exe set site '/site.name:"WebRole_IN_0_CB"' "/[Path='/'].applicationPool:`"ASP.NET v4.0`"" >CBLog.log
if($lastexitcode -ne '0')
{
    while($lastexitcode -ne '0')
    {
        Start-Sleep -s 5
        & $Env:WinDir\system32\inetsrv\appcmd.exe set site '/site.name:"WebRole_IN_0_CB"' "/[Path='/'].applicationPool:`"ASP.NET v4.0`"" >CBLog.log
    }
}

Actualización II:Lo he escapado correctamente. Pero aún así recibo el mensaje de error. Si ejecuto solo el APPCMD después de crear ese sitio, el archivo de registro está bien. ¿Alguna sugerencia por favor?

¿Fue útil?

Solución

La variable especial $lastexitcode Te da el código de salida del último ejecutable nativo (es decir, no cmdlet) que se ejecutó. Esto tendrá diferentes valores dependiendo de los resultados de la operación. Por ejemplo, serán 5 si APPCMD encuentra el acceso al acceso. Debe ser 0 si el último comando completó la éxito.

Asegúrese de verificar esta variable inmediatamente después de ejecutar APPCMD y en el mismo script. Si no es así, corre el riesgo de obtener el código de salida de PowerShell.exe y no de AppCmd.exe

Otros consejos

Me doy cuenta de que el problema original probablemente se ha resuelto, pero en aras de los Googlers que golpean esta pregunta, escribí una función de propósito general (avanzado) para volver a intentar los comandos de Shell (CMD). Además de $ lastExitCode, también puede analizar la secuencia de errores (con algunas herramientas, el código de salida puede ser una mentira).

function Call-CommandWithRetries
{
 [CmdletBinding()]
 param( 
     [Parameter(Mandatory=$True)]
     [string]$Command,
     [Array]$Arguments,
     [bool]$TrustExitCode = $True,
     [int]$RetrySleepSeconds = 10,
     [int]$MaxAttempts = 10,
     [bool]$PrintCommand = $True
 )

 Process
 {
  $attempt = 0
  while ($true)
  {   
   Write-Host $(if ($PrintCommand) {"Executing: $Command $Arguments"} else {"Executing command..."}) 
   & $Command $Arguments 2>&1 | tee -Variable output | Write-Host

   $stderr = $output | where { $_ -is [System.Management.Automation.ErrorRecord] }
   if ( ($LASTEXITCODE -eq 0) -and ($TrustExitCode -or !($stderr)) )
   {
    Write-Host "Command executed successfully"
    return $output
   }

   Write-Host "Command failed with exit code ($LASTEXITCODE) and stderr: $stderr" -ForegroundColor Yellow
   if ($attempt -eq $MaxAttempts)
   {
    $ex = new-object System.Management.Automation.CmdletInvocationException "All retry attempts exhausted"
    $category = [System.Management.Automation.ErrorCategory]::LimitsExceeded
    $errRecord = new-object System.Management.Automation.ErrorRecord $ex, "CommandFailed", $category, $Command
    $psCmdlet.WriteError($errRecord)
    return $output
   }

   $attempt++;
   Write-Host "Retrying test execution [#$attempt/$MaxAttempts] in $RetrySleepSeconds seconds..."
   Start-Sleep -s $RetrySleepSeconds
  }
 }
}

Para obtener más información (incluida la documentación completa), consulte https://www.ohadsoft.com/2016/04/invoking-arbitrary-shell-cmd-commands-inpowershell.

En tu caso harías algo como

$appCmd = [io.path]::combine($env:WINDIR, 'system32', 'inetsrv', 'appcmd.exe')
$appCmdArg = @('set', 'site', '/site.name:"WebRole_IN_0_CB"', '/[Path=''/''].applicationPool:"ASP.NET v4.0"')
$output = Call-CommandWithRetries $appCmd $appCmdArgs
# write $output to log etc
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top