Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Applies to: ✔️ máquinas virtuales de Windows
Resumen
En este artículo se describe cómo probar y corregir un error en un script de PowerShell que usa la característica Extensión de script personalizado o Ejecutar comando.
Importante
Nuevo Pruebe la asistencia de máquina virtual para resolver los principales problemas. Se recomienda ejecutar VM assist for Windows o VM assist for Linux. Estas herramientas de diagnóstico basadas en scripts le ayudan a identificar problemas comunes que afectan al agente invitado de máquina virtual Azure y el estado general de las máquinas virtuales.
Si experimenta problemas de rendimiento en las máquinas virtuales, ejecute estas herramientas primero antes de ponerse en contacto con Soporte técnico de Microsoft.
Requisitos previos
Información general
Supongamos que usó la Extensión de Script Personalizado o Ejecutar comando para ejecutar un script de PowerShell. ¿Qué hace si se produce un error en el script? Tiene varios métodos disponibles para determinar la causa del error.
PowerShell tiene más de un flujo de salida. Los registros de la extensión de script personalizado y los scripts Ejecutar comando envían la secuencia de Éxito al StdOut subestado y la secuencia de Error al StdErr subestado. Estos subestados pertenecen a la extensión usada para ejecutar el script de la Extensión de Script Personalizado o el script de Ejecutar Comando.
Los subestados StdOut y StdErr están en la vista de instancia del punto de registro de certificados (CRP) para la máquina virtual (VM). Estos subestados son visibles en diferentes ubicaciones, como se muestra en la tabla siguiente.
| Interfaz | Cómo ver el subestado |
|---|---|
| Azure portal |
|
| Azure PowerShell | Escriba el cmdlet Get-AzVM para obtener las propiedades de una máquina virtual de Azure, como se indica a continuación:Get-AzVM -ResourceGroupName <resource-group-name> -Name <vm-name> -Status |
| CLI de Azure | Escriba el comando az vm get-instance-view para obtener información de instancia sobre una máquina virtual de Azure, como se indica a continuación:az vm get-instance-view --resource-group <resource-group-name> --name <vm-name> --query instanceView.extensions |
El error que normalmente hace que el script falle aparece en el StdErr subestado. Sin embargo, los scripts también pueden fallar sin registrar una entrada de error fatal en ese subestado.
Probar el script manualmente y mediante PsExec
Compruebe manualmente que el script se ejecuta correctamente desde una consola administrativa de PowerShell en la máquina virtual.
Si el script funciona manualmente, use PsExec para ejecutar el script mediante la cuenta del sistema local. Para la Extensión de Script Personalizado y el Run Command, los scripts se ejecutan mediante esa cuenta. Al introducir psexec -s, puede probar el script utilizando la cuenta del sistema local, pero sin utilizar ni la Extensión de Script Personalizado ni el Comando Ejecutar. Si el error se reproduce con psexec -s, entonces la Extensión de Script Personalizado y el Comando Ejecutar no son la causa del problema.
Prueba mediante PsExec
Puede usar PsExec para ejecutar un script de prueba de PowerShell de forma remota. Abra una ventana de comandos con privilegios administrativos y luego ingrese el siguiente comando PsExec. Reemplace el marcador de posición por el nombre completo del script de PowerShell:
psexec -accepteula -nobanner -s powershell.exe -NoLogo -NoProfile -File <C:\path\script-name.ps1>
O bien, puede usar PsExec de forma interactiva. En el ejemplo siguiente, escriba el comando whoami para mostrar que PowerShell se ejecuta en la cuenta del sistema local (NT AUTHORITY\SYSTEM):
C:\>psexec -accepteula -nobanner -s powershell.exe -NoLogo -NoProfile
PS C:\Windows\system32> whoami
nt authority\system
Activación del registro de la ejecución de scripts de PowerShell
Si el StdErr subestado no muestra la causa del problema, puede activar varios tipos de registro para mostrar colectivamente el contenido y la salida del script. Este registro muestra lo que intenta lograr el script y el resultado de ejecutar el script.
Para activar diferentes tipos de registro, siga los pasos descritos en las siguientes secciones.
Advertencia
Algunas de las instrucciones implican cambiar el registro de Windows. Es posible que se produzcan problemas graves si modifica el Registro de forma incorrecta mediante el Editor del Registro u otro método. Estos problemas pueden requerir la reinstalación del sistema operativo. Microsoft no puede garantizar que estos problemas se puedan resolver. Realice primero una copia de seguridad de las entradas del Registro existentes y, a continuación, modifique el registro en su propio riesgo.
Aumento del tamaño máximo de los registros de eventos
Se puede generar un gran número de eventos tanto en el registro de seguridad como en el registro de eventos de Microsoft-Windows-PowerShell/Operational. Para evitar la pérdida de estos eventos registrados, aumente el tamaño máximo de los registros. Pero si cualquiera de estos registros tiene el tamaño máximo de 100 MB o mayor (un maxSize valor de 104 857 600 o más), deje el valor de tamaño máximo tal como está.
Para comprobar el tamaño máximo del registro, use el comando wevtutil y la get-log opción para recuperar información sobre los registros de eventos:
wevtutil get-log "Security"
wevtutil get-log "Microsoft-Windows-PowerShell/Operational"
Verá un resultado que se asemeja al texto siguiente. En estos casos, el tamaño máximo del registro es mucho menor que 100 MB.
name: Security
enabled: true
type: Admin
owningPublisher:
isolation: Custom
channelAccess: O:BAG:SYD:(A;;CCLCSDRCWDWO;;;SY)(A;;CCLC;;;BA)(A;;CC;;;ER)(A;;CC;;;NS)
logging:
logFileName: %SystemRoot%\System32\Winevt\Logs\Security.evtx
retention: false
autoBackup: false
maxSize: 20971520
publishing:
fileMax: 1
name: Microsoft-Windows-PowerShell/Operational
enabled: true
type: Operational
owningPublisher: Microsoft-Windows-PowerShell
isolation: Application
channelAccess: O:BAG:SYD:(A;;0x2;;;S-1-15-2-1)(A;;0x2;;;S-1-15-3-1024-3153509613-960666767-3724611135-2725662640-12138253-543910227-1950414635-4190290187)(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)(A;;0x3;;;S-1-5-33)(A;;0x1;;;S-1-5-32-573)
logging:
logFileName: %SystemRoot%\System32\Winevt\Logs\Microsoft-Windows-PowerShell%4Operational.evtx
retention: false
autoBackup: false
maxSize: 15728640
publishing:
fileMax: 1
Para aumentar el tamaño máximo del registro de seguridad o del registro de eventos de Microsoft-Windows-PowerShell/Operational a 100 MB, ejecute wevtutil junto con la opción set-log:
wevtutil set-log "Security" /ms:104857600
wevtutil set-log "Microsoft-Windows-PowerShell/Operational" /ms:104857600
Activar la auditoría de creación de procesos
Use el siguiente comando para activar la auditoría de creación de procesos:
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v "ProcessCreationIncludeCmdLine_Enabled" /t REG_DWORD /d 1 /f
Activación de la transcripción de PowerShell
reg add "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\Transcription" /v "EnableTranscripting" /t REG_DWORD /d 1 /f
reg add "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\Transcription" /v "EnableInvocationHeader" /t REG_DWORD /d 1 /f
reg add "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\Transcription" /v "OutputDirectory" /t REG_SZ /d C:\Transcripts /f
Activar el registro de módulos de PowerShell
reg add "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging" /v "EnableModuleLogging" /t REG_DWORD /d 1 /f
reg add "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames" /v "*" /t REG_SZ /d *
Activar el registro de bloques de scripts de PowerShell
reg add "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v "EnableScriptBlockLogging" /t REG_DWORD /d 1 /f
Descripción de la salida
La auditoría de la creación de procesos escribirá el identificador de evento 4688 y el identificador de evento 4689 en el registro de eventos de seguridad. El identificador de evento 4688 es para la creación del proceso e incluye la línea de comandos de proceso. El identificador de evento 4689 es para la finalización del proceso.
La transcripción crea un archivo de texto en el directorio C:\Transcripciones\<output-date> . El directorio se creará automáticamente si aún no existe.
Por ejemplo:
C:\transcripts\20201211\PowerShell_transcript.<vm-name>.a+BWp8CT.20201211034929.txt
El registro de módulos registrará el identificador de evento 4103 en el registro de eventos de Microsoft-Windows-PowerShell/Operational. El evento "4103" incluye el nombre y la salida del cmdlet.
Si ejecuta Write-Host $Env:ComputerName, la parte superior del id. de evento 4013 muestra el texto siguiente, donde value="<vm-name>" indica que la salida del comando era el nombre de la máquina virtual:
CommandInvocation(Write-Host): "Write-Host"
ParameterBinding(Write-Host): name="Object"; value="<vm-name>"
El registro de bloques de script registrará el identificador de evento 4104 en el registro de eventos Microsoft-Windows-PowerShell/Operational. Los eventos "4104" contienen el contenido del script. Los scripts que superan el tamaño máximo de mensaje de un evento se registran como varios eventos "4104".
Después de activar el registro y reproducir el error del script, ejecute el siguiente script para exportar los eventos pertinentes a un archivo de valor separado por comas (CSV). La consulta siguiente examina las 24 horas anteriores (86 400 000 milisegundos) de datos. Escriba el valor 36000000 para recuperar solo la hora más reciente. El valor 6048000000 recuperará la semana más reciente.
$path = "PSEvents_$($env:COMPUTERNAME)_$(Get-Date ((Get-Date).ToUniversalTime()) -Format yyyyMMddHHmmss).csv"
$hours = 1 # Increase this to have it query more than just the last 1 hour
$now = Get-Date
$startTimeUtc = Get-Date ($now.AddHours(-$hours).ToUniversalTime()) -Format 'yyyy-MM-ddTHH:mm:ssZ'
$endTimeUtc = Get-Date ($now.ToUniversalTime()) -Format 'yyyy-MM-ddTHH:mm:ssZ'
$filterXML = @"
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
Event
[
System
[
(EventID = '4688' or EventID = '4689')
and
TimeCreated
[
@SystemTime >= '$startTimeUtc'
and
@SystemTime <= '$endTimeUtc'
]
]
and
EventData
[
Data[@Name="SubjectUserSid"] = "S-1-5-18"
]
]
</Select>
</Query>
<Query Id="1" Path="Microsoft-Windows-PowerShell/Operational">
<Select Path="Microsoft-Windows-PowerShell/Operational">
Event
[
System
[
(EventID ='4103' or EventID ='4104')
and
Security
[
@UserID ='S-1-5-18'
]
and
TimeCreated
[
@SystemTime >= '$startTimeUtc'
and
@SystemTime <= '$endTimeUtc'
]
]
]
</Select>
</Query>
</QueryList>
"@
$events = Get-WinEvent -FilterXml $filterXML | Sort-Object -Property RecordId
$events = $events | Select-Object -Property RecordId,
TimeCreated, Id, MachineName, LogName, TaskDisplayName, Message
$events | Export-Csv -Path $path -NoTypeInformation
Desactivación del registro de la ejecución de scripts de PowerShell
Para deshacer los cambios realizados para habilitar el registro de scripting de PowerShell en la máquina virtual, siga estos pasos:
Si anteriormente aumentó el tamaño máximo del registro de seguridad o del registro de Microsoft-Windows-PowerShell/Operational, revierta esos valores a los tamaños máximos predeterminados:
wevtutil set-log "Security" /ms:20971520 wevtutil set-log "Microsoft-Windows-PowerShell/Operational" /ms:15728640Desactivar la auditoría de creación de procesos:
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v "ProcessCreationIncludeCmdLine_Enabled" /t REG_DWORD /d 0 /fDesactivar la transcripción:
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" /v "EnableTranscripting" /t REG_DWORD /d 0 /f reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" /v "EnableInvocationHeader" /t REG_DWORD /d 0 /f reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" /v "OutputDirectory"Desactivar el registro de módulos:
reg add "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging" /v "EnableModuleLogging" /t REG_DWORD /d 0 /f reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames" /v "*"Desactivar el registro de bloques de script:
reg add "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v "EnableScriptBlockLogging" /t REG_DWORD /d 0 /fQuite la carpeta de transcripción:
Remove-Item -Path 'C:\Transcripts' -Force -RecurseRealice una copia de seguridad y borre el registro de seguridad o el de Microsoft-Windows-PowerShell/Operational:
wevtutil clear-log Security /bu:Security.evtx wevtutil clear-log Microsoft-Windows-PowerShell/Operational /bu:Microsoft-Windows-PowerShell_Operational.evtxO borre el registro de seguridad y el registro de Microsoft-Windows-PowerShell/Operational sin realizar una copia de seguridad de ellos:
wevtutil clear-log Security wevtutil clear-log Microsoft-Windows-PowerShell/Operational
Prueba del registro de comandos de ejecución en la máquina virtual
Descargue el script de prueba Test-CustomScriptExtension.ps1 en el directorio local actual. A continuación, ejecute el script en la máquina virtual mediante el cmdlet Invoke-AzVMRunCommand . Use las propiedades de la máquina virtual para reemplazar los marcadores de posición del nombre del grupo de recursos y el nombre de la máquina virtual.
$scriptUri = 'https://raw.githubusercontent.com/Azure/azure-support-scripts/blob/users/GitHubPolicyService/6294a303-e34d-4bad-b6cd-5ed54245f020/Images_Extensions/PowerShell/Test-CustomScriptExtension.ps1'
$localFileLocation = "$PWD\Test-CustomScriptExtension.ps1"
(New-Object System.Net.WebClient).DownloadFile($scriptUri, $localFileLocation)
$commandSettings = @{
ResourceGroupName = '<resource-group-name>'
VMName = '<vm-name>'
CommandId = 'RunPowerShellScript'
ScriptPath = $localFileLocation
}
Invoke-AzVMRunCommand @commandSettings
Prueba del registro de la extensión de script personalizado en la máquina virtual
Ejecute el script de prueba Test-CustomScriptExtension.ps1 en la máquina virtual mediante el cmdlet Set-AzVMCustomScriptExtension. Use las propiedades de la máquina virtual para reemplazar los marcadores de posición del nombre del grupo de recursos, el nombre de la máquina virtual y la ubicación.
$commandSettings = @{
ResourceGroupName = '<resource-group-name>'
VMName = '<vm-name>'
Name = 'CustomScriptExtension'
FileUri = 'https://raw.githubusercontent.com/Azure/azure-support-scripts/blob/users/GitHubPolicyService/6294a303-e34d-4bad-b6cd-5ed54245f020/Images_Extensions/PowerShell/Test-CustomScriptExtension.ps1'
Run = 'Test-CustomScriptExtension.ps1'
Location = '<azure-region-name-or-code>'
ForceRerun = (Get-Date).Ticks
}
Set-AzVMCustomScriptExtension @commandSettings
Como alternativa, puede ejecutar ese script de prueba en la máquina virtual mediante el cmdlet Set-AzVMExtension . Tendrá que especificar un parámetro `ExtensionType` junto con varios otros cambios de parámetros `CustomScriptExtension`. Use las propiedades de la máquina virtual para reemplazar los marcadores de posición del nombre del grupo de recursos, el nombre de la máquina virtual y la ubicación.
$publicConfigSettings = @{
'fileUris' = @('https://raw.githubusercontent.com/Azure/azure-support-scripts/blob/users/GitHubPolicyService/6294a303-e34d-4bad-b6cd-5ed54245f020/Images_Extensions/PowerShell/Test-CustomScriptExtension.ps1')
'commandToExecute' = 'powershell -File Test-CustomScriptExtension.ps1 -ExecutionPolicy Unrestricted'
}
$commandSettings = @{
Publisher = 'Microsoft.Compute'
ExtensionType = 'CustomScriptExtension'
Settings = $publicConfigSettings
ResourceGroupName = '<resource-group-name>'
VMName = '<vm-name>'
Name = 'CustomScriptExtension'
TypeHandlerVersion = '1.10'
Location = '<azure-region-name-or-code>'
}
Set-AzVMExtension @commandSettings
Errores comunes en el script de prueba de la Extensión de Script Personalizado
Código de salida distinto de cero: después de ejecutar el script Test-CustomScriptExtension.ps1 , espere recibir el siguiente mensaje de error:
La operación de larga ejecución falló con el estado "Falló".
Información adicional: la máquina virtual ha notificado un error al procesar la extensión "CustomScriptExtension".
Mensaje de error: "La ejecución del comando finalizó, pero se produjo un error porque devolvió un código de salida distinto de cero de: '2'"El script de prueba ejecuta el comando
Exit 2, y se espera que la Extensión de Script Personalizado falle intencionadamente si el script devuelve un código de salida distinto de cero. (En este ejemplo, 2 es el código de salida distinto de cero). En este ejemplo se muestra cómo aparece un error en el registro adicional de PowerShell que ha habilitado.Cambio está en conflicto: Este error indica que la máquina virtual ya tiene instalada la extensión Custom Script como recurso con el nombre Microsoft.Compute.CustomScriptExtension, pero está especificando un nombre de recurso diferente, CustomScriptExtension, para la ejecución actual.
No se puede actualizar "handlerVersion" o "autoUpgradeMinorVersion" para la extensión de máquina virtual "CustomScriptExtension".
El cambio está en conflicto con otras extensiones bajo el controlador 'Microsoft.Compute.CustomScriptExtension', con la versión del controlador de tipo '1.10' y autoUpgradeMinorVersion 'True'.
ErrorCode: OperaciónNoPermitida
ErrorMessage: No se puede actualizar handlerVersion o autoUpgradeMinorVersion para la extensión de máquina virtual "CustomScriptExtension".
El cambio está en conflicto con otras extensiones en el controlador 'Microsoft Compute CustomScriptExtension', con versión de typeHandler '1.10' y autoUpgradeMinorVersion 'True'.
ErrorTarget:
StatusCode: 409
ReasonPhrase: ConflictoPuede especificar lo que desee para el nombre del recurso. Sin embargo, si ya tiene instalada la extensión de script personalizado, debe realizar cualquiera de las siguientes acciones:
- Use el mismo nombre para las ejecuciones posteriores.
- En primer lugar, quite ese recurso de extensión antes de usar un nombre de recurso diferente.
Configuración de URI de archivo no válida: este error indica que la extensión de script personalizado se instaló originalmente junto con los URI de archivo especificados en la configuración protegida, pero ahora se especifican en la configuración pública (o viceversa):
La operación de larga ejecución falló con el estado 'Fallido'.
Información adicional: la máquina virtual ha notificado un error al procesar la extensión "CustomScriptExtension".
Mensaje de error: "Configuración no válida: FileUris está presente en las secciones de configuración protegida y pública; debe especificarse en una sola sección".
Soluciones a errores comunes en el script de prueba de la extensión de script personalizado
Para corregir el error "El cambio está en conflicto", intente volver a ejecutar
Set-AzVMCustomScriptExtensionoSet-AzVMExtension, pero establezca el parámetro-Nameal nombre del recurso de la extensión de script personalizado que ya está instalado en la máquina virtual. Para el error de ejemplo, al quitar la extensión, especifique un parámetro-Namede Microsoft. Compute.CustomScriptExtension. Pero el-Nameparámetro debe coincidir con el nombre del recurso de la extensión que ya está instalada en la máquina virtual.El nombre que se va a usar para
-Nameserá el nombre del recurso en esta parte del error: "El cambio está en conflicto con otras extensiones en el controlador "<resource-name>".También puede comprobar el nombre de recurso correcto para usar obteniéndolo del estado de la máquina virtual. Escriba el cmdlet Get-AzVM , como se indica a continuación:
$status = Get-AzVM -ResourceGroupName <resource-group> -Name <vm-name> -Status $status.Extensions | Where-Object Type -EQ 'Microsoft.Compute.CustomScriptExtension' | Select-Object NamePara mitigar el error "El cambio está en conflicto" y el error "FileUris", puede eliminar la extensión de script personalizado existente ingresando el cmdlet Remove-AzVMCustomScriptExtension:
$params = @{ ResourceGroupName = '<resourceGroupName>' VMName = '<vm-name>' Name = '<extension-resource-name>' Force = $True } Remove-AzVMCustomScriptExtension @paramsSi especifica el nombre de recurso incorrecto, el valor devuelto
StatusCodeesNoContent:RequestId IsSuccessStatusCode StatusCode ReasonPhrase --------- ------------------- ---------- ------------ True NoContent No ContentSi especifica el nombre de recurso correcto, el valor devuelto
StatusCodeesOK:RequestId IsSuccessStatusCode StatusCode ReasonPhrase --------- ------------------- ---------- ------------ True OK OK
Referencias
- Solución de problemas con las extensiones de máquina virtual de Azure Windows
- Seguimiento y registro de scripts
- Identificadores de seguridad bien conocidos en sistemas operativos Windows
- Registro de eventos de Windows
- Evento de creación de procesos auditados con éxito
- Configuración de Windows - Configurar un sistema víctima
Aviso de declinación de responsabilidades sobre la información de contacto de terceros
Microsoft proporciona información de contacto de terceros para ayudarle a encontrar información adicional sobre este tema. Esta información de contacto puede cambiar sin previo aviso. Microsoft no garantiza la precisión de la información de contacto de terceros.