Dela via


Felsöka PowerShell-skript som körs av tillägget för anpassat skript eller kör kommandot

Gäller för: ✔️ Virtuella Windows-datorer

I den här artikeln beskrivs hur du testar och korrigerar för ett fel i ett PowerShell-skript som använder tillägget för anpassat skript eller funktionen Kör kommando.

Viktigt!

Nytt! Prova VM-hjälpen för att lösa de vanligaste problemen. Vi rekommenderar att du kör VM-hjälpen för Windows eller VM-hjälpen för Linux. Dessa skriptbaserade diagnostikverktyg hjälper dig att identifiera vanliga problem som påverkar gästagenten för virtuella Azure-datorer och övergripande hälsotillstånd för virtuella datorer.

Om du har prestandaproblem på virtuella datorer kör du de här verktygen först innan du kontaktar Microsoft Support.

Förutsättningar

Översikt

Anta att du använde funktionen Anpassat skripttillägg eller Kör kommando för att köra ett PowerShell-skript. Vad gör du om skriptet misslyckas? Du har flera tillgängliga metoder för att fastställa orsaken till felet.

PowerShell har mer än en utdataström. Loggar för anpassade skripttillägg och körningskommandoskript skickar dataströmmen Lyckades till StdOut understatusen och felströmmen till understatusen StdErr . Dessa understatusar tillhör tillägget som användes för att köra skriptet för anpassat skripttillägg eller kör kommandoskriptet.

Och StdOutStdErr understatusar finns i instansvyn för certifikatregistreringsplatsen (CRP) för den virtuella datorn (VM). Dessa understatusar visas på flera platser, enligt följande tabell.

Gränssnitt Så här visar du understatusen
Azure-portalen
  1. Sök efter Virtuella datorer.
  2. Välj den virtuella datorn i listan.
  3. På översiktssidan för den virtuella datorn väljer du Tillägg + programtillägg>.
  4. Välj det tillägg som användes för att köra kommandot. (Den kommer att namnges antingen CustomScriptExtension eller RunCommand.)
  5. Välj Visa detaljerad status.
Azure PowerShell Ange cmdleten Get-AzVM för att hämta egenskaperna för en virtuell Azure-dator enligt följande:
Get-AzVM -ResourceGroupName <resource-group-name> -Name <vm-name> -Status
Azure CLI Ange kommandot az vm get-instance-view för att hämta instansinformation om en virtuell Azure-dator enligt följande:
az vm get-instance-view --resource-group <resource-group-name> --name <vm-name> --query instanceView.extensions

Felet som vanligtvis gör att skriptet misslyckas visas i understatusen StdErr . Skript kan dock också misslyckas utan att logga en dödlig felpost i understatusen.

Testa skriptet manuellt och med PsExec

Kontrollera att skriptet körs manuellt från en administrativ PowerShell-konsol på den virtuella datorn.

Om skriptet fungerar manuellt använder du PsExec för att köra skriptet med hjälp av det lokala systemkontot. För både Anpassat skripttillägg och Kör kommando körs skript med hjälp av det kontot. Genom att ange psexec -skan du testa skriptet med hjälp av det lokala systemkontot, men utan att använda antingen Anpassat skripttillägg eller Kör kommando. Om felet återskapas med hjälp psexec -sav är det anpassade skripttillägget och körningskommandot inte orsaken till problemet.

Testa med PsExec

Du kan använda PsExec för att fjärrköra ett PowerShell-testskript. Öppna ett administrativt kommandotolkfönster och ange sedan följande PsExec-kommando. Ersätt platshållaren med det fullständigt kvalificerade namnet på PowerShell-skriptet:

psexec -accepteula -nobanner -s powershell.exe -NoLogo -NoProfile -File <C:\path\script-name.ps1>

Eller så kan du använda PsExec interaktivt. I följande exempel anger du kommandot whoami för att visa att PowerShell körs under kontot Lokalt system (NT AUTHORITY\SYSTEM):

C:\>psexec -accepteula -nobanner -s powershell.exe -NoLogo -NoProfile

PS C:\Windows\system32> whoami
nt authority\system 

Aktivera loggning av PowerShell-skriptkörning

Om understatusen StdErr inte visar orsaken till problemet kan du aktivera flera typer av loggning för att kollektivt visa skriptinnehållet och utdata. Den här loggningen visar vad skriptet försöker åstadkomma och resultatet av att köra skriptet.

Om du vill aktivera olika typer av loggning följer du stegen i de kommande avsnitten.

Varning

Några av instruktionerna omfattar ändring av Windows-registret. Varning: Allvarliga problem kan uppstå om du felaktigt ändrar registret med hjälp av Registereditorn eller med en annan metod. Dessa problem kan kräva att du installerar om operativsystemet. Microsoft kan inte garantera att problemen kan lösas. Säkerhetskopiera dina befintliga registerposter först och ändra sedan registret på egen risk.

Öka den maximala storleken på händelseloggarna

Ett stort antal händelser kan genereras i både säkerhetsloggen och händelseloggen Microsoft-Windows-PowerShell/Operational. Om du vill förhindra förlust av dessa loggade händelser ökar du den maximala storleken på loggarna. Men om någon av dessa loggar har en maximal storlek på 100 MB eller större (ett maxSize värde på 104 857 600 eller mer) lämnar du den maximala storleksinställningen som den är.

Om du vill kontrollera loggens maximala storlek använder du kommandot wevtutil och get-log alternativet för att hämta information om händelseloggar:

wevtutil get-log "Security"
wevtutil get-log "Microsoft-Windows-PowerShell/Operational"

Du ser utdata som liknar följande text. I dessa fall är den maximala loggstorleken mycket mindre än 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

Om du vill öka den maximala storleken på säkerhetsloggen eller händelseloggen Microsoft-Windows-PowerShell/Operational till 100 MB kör du wevtutil tillsammans med set-log alternativet:

wevtutil set-log "Security" /ms:104857600
wevtutil set-log "Microsoft-Windows-PowerShell/Operational" /ms:104857600

Aktivera granskning av processskapande

Använd följande kommando för att aktivera granskning av processskapande:

reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v "ProcessCreationIncludeCmdLine_Enabled" /t REG_DWORD /d 1 /f

Aktivera PowerShell-transkription

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

Aktivera Loggning av PowerShell-modul

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 *

Aktivera Blockloggning av PowerShell-skript

reg add "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v "EnableScriptBlockLogging" /t REG_DWORD /d 1 /f

Förstå utdata

Granskning av processskapandet skriver händelse-ID 4688 och händelse-ID 4689 till händelseloggen Säkerhet. Händelse-ID 4688 är till för att skapa processer och innehåller kommandoraden Process. Händelse-ID 4689 är för processavslut.

Transkription skapar en textfil i katalogen C:\Transcripts\<output-date> . Katalogen skapas automatiskt om den inte redan finns.

Till exempel:

C:\transcripts\20201211\PowerShell_transcript.<vm-name>.a+BWp8CT.20201211034929.txt

Modulloggning loggar händelse-ID 4103 till händelseloggen Microsoft-Windows-PowerShell/Operational. Händelsen "4103" innehåller cmdletens namn och utdata.

Om du kör Write-Host $Env:ComputerNamevisar överst i händelse-ID 4013 följande text, där value="<vm-name>" anger att kommandots utdata var namnet på den virtuella datorn:

CommandInvocation(Write-Host): "Write-Host"
ParameterBinding(Write-Host): name="Object"; value="<vm-name>"

Loggning av skriptblock loggar händelse-ID 4104 till händelseloggen Microsoft-Windows-PowerShell/Operational . Händelserna "4104" innehåller innehållet i skriptet. Skript som överskrider den maximala meddelandestorleken för en händelse loggas som flera "4104"-händelser.

När du har aktiverat loggningen och återskapat skriptfelet kör du följande skript för att exportera relevanta händelser till en CSV-fil (kommaavgränsat värde). Följande fråga undersöker de senaste 24 timmarna (86 400 000 millisekunder) data. Ange värdet 3600000 för att hämta endast den senaste timmen. Värdet 604800000 hämtar den senaste veckan.

$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 &gt;= '$startTimeUtc'
                        and
                        @SystemTime &lt;= '$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 &gt;= '$startTimeUtc'
                        and
                        @SystemTime &lt;= '$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

Inaktivera loggning av PowerShell-skriptkörning

Utför följande steg för att ångra de ändringar som du har gjort för att aktivera loggning av PowerShell-skript på den virtuella datorn:

  1. Om du tidigare har ökat den maximala storleken på säkerhetsloggen eller Microsoft-Windows-PowerShell/Operational-loggen återställer du dessa värden till standardstorlekarna:

    wevtutil set-log "Security" /ms:20971520
    wevtutil set-log "Microsoft-Windows-PowerShell/Operational" /ms:15728640
    
  2. Inaktivera granskning av processskapande:

    reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v "ProcessCreationIncludeCmdLine_Enabled" /t REG_DWORD /d 0 /f
    
  3. Inaktivera transkription:

    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"
    
  4. Inaktivera modulloggning:

    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 "*"
    
  5. Inaktivera loggning av skriptblock:

    reg add "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v "EnableScriptBlockLogging" /t REG_DWORD /d 0 /f
    
  6. Ta bort transkriptionsmappen:

    Remove-Item -Path 'C:\Transcripts' -Force -Recurse
    
  7. Säkerhetskopiera och rensa säkerhetsloggen och Microsoft-Windows-PowerShell/Driftloggen:

    wevtutil clear-log Security /bu:Security.evtx
    wevtutil clear-log Microsoft-Windows-PowerShell/Operational /bu:Microsoft-Windows-PowerShell_Operational.evtx
    

    Eller rensa säkerhetsloggen och Microsoft-Windows-PowerShell/Driftloggen utan att säkerhetskopiera dem:

    wevtutil clear-log Security
    wevtutil clear-log Microsoft-Windows-PowerShell/Operational
    

Testkörningskommandologgning på den virtuella datorn

Ladda ned testskriptet Test-CustomScriptExtension.ps1 till den aktuella lokala katalogen. Kör sedan skriptet på den virtuella datorn med hjälp av cmdleten Invoke-AzVMRunCommand . Använd egenskaperna för den virtuella datorn för att ersätta platshållarna för resursgruppens namn och vm-namn.

$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

Testa loggning av anpassat skripttillägg på den virtuella datorn

Kör testskriptet Test-CustomScriptExtension.ps1 på den virtuella datorn med hjälp av cmdleten Set-AzVMCustomScriptExtension . Använd egenskaperna för den virtuella datorn för att ersätta platshållarna för resursgruppens namn, VM-namn och plats.

$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

Du kan också köra testskriptet på den virtuella datorn med hjälp av cmdleten Set-AzVMExtension . Du måste ange en ExtensionType parameter CustomScriptExtension för tillsammans med flera andra parameterändringar. Använd egenskaperna för den virtuella datorn för att ersätta platshållarna för resursgruppens namn, VM-namn och plats.

$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

Vanliga fel i testskriptet för anpassat skripttillägg

  • Icke-nollavslutskod: När du har kört skriptet Test-CustomScriptExtension.ps1 förväntar du dig att få följande felmeddelande:

    Tidskrävande åtgärd misslyckades med statusen "Misslyckades".
    Ytterligare information: Den virtuella datorn har rapporterat ett fel vid bearbetning av tillägget "CustomScriptExtension".
    Felmeddelande: "Kommandokörningen slutfördes, men misslyckades eftersom den returnerade en slutkod som inte var noll för: '2'"

    Testskriptet kör Exit 2 kommandot och tillägget för anpassat skript förväntas misslyckas avsiktligt om skriptet returnerar en slutkod som inte är noll. (I det här exemplet är 2 den icke-nollavslutskod.) Det här exemplet visar hur ett fel visas i den extra PowerShell-loggning som du har aktiverat.

  • Ändringen är i konflikt: Det här felet anger att det anpassade skripttillägget redan har installerats som resursnamn Microsoft.Compute.CustomScriptExtension, men du anger ett annat resursnamn för CustomScriptExtension för den aktuella körningen:

    Det går inte att uppdatera handlerVersion eller autoUpgradeMinorVersion för VM-tillägget "CustomScriptExtension".
    Ändringen står i konflikt med andra tillägg under hanteraren "Microsoft.Compute.CustomScriptExtension", med typeHandler-versionen "1.10" och autoUpgradeMinorVersion "True".
    ErrorCode: ÅtgärdEjTillåten
    ErrorMessage: Det går inte att uppdatera handlerVersion eller autoUpgradeMinorVersion för VM-tillägget "CustomScriptExtension".
    Ändringen står i konflikt med andra tillägg under hanteraren "Microsoft.Compute.CustomScriptExtension", med typeHandler-versionen "1.10" och autoUpgradeMinorVersion "True".
    ErrorTarget:
    StatusCode: 409
    ReasonPhrase: Konflikt

    Du kan ange vad du vill för resursnamnet. Men om du redan har tillägget för anpassat skript installerat måste du vidta någon av följande åtgärder:

    • Använd samma namn för efterföljande körningar.
    • Ta först bort tilläggsresursen innan du använder ett annat resursnamn.
  • Ogiltig fil-URI-konfiguration: Det här felet anger att tillägget för anpassat skript ursprungligen installerades tillsammans med fil-URI:er som anges i skyddade inställningar, men som nu anges i offentliga inställningar (eller vice versa):

    Tidskrävande åtgärd misslyckades med statusen "Misslyckades".
    Ytterligare information: Den virtuella datorn har rapporterat ett fel vid bearbetning av tillägget "CustomScriptExtension".
    Felmeddelande: "Ogiltig konfiguration – FileUris finns i både de skyddade och offentliga konfigurationsavsnitten; det måste anges i endast ett avsnitt."

Lösningar på vanliga fel i testskriptet för anpassat skripttillägg

  • Om du vill åtgärda felet "Ändringen är i konflikt" försöker du köra Set-AzVMCustomScriptExtension eller Set-AzVMExtension, men ange parametern -Name till resursnamnet för resursnamn för resursen för det anpassade skripttillägget som redan är installerat på den virtuella datorn. För exempelfelet anger du en -Name parameter för Microsoft.Compute.CustomScriptExtension när du tar bort tillägget. Men parametern -Name måste vara det resursnamn som är för tilläggsresursen som redan är installerad på den virtuella datorn.

    Namnet som ska användas för -Name är resursnamnet i den här delen av felet: "Ändringen står i konflikt med andra tillägg under hanteraren "<resursnamn>".

    Du kan också verifiera rätt resursnamn som ska användas genom att hämta det från vm-statusen. Ange Get-AzVM-cmdleten enligt följande:

    $status = Get-AzVM -ResourceGroupName <resource-group> -Name <vm-name> -Status
    $status.Extensions |
    Where-Object Type -EQ 'Microsoft.Compute.CustomScriptExtension' |
    Select-Object Name
    
  • För att minimera felet "Ändring är i konflikt" och "FileUris"-felet kan du ta bort det befintliga tillägget för anpassat skript genom att ange cmdleten Remove-AzVMCustomScriptExtension :

    $params = @{
        ResourceGroupName = '<resourceGroupName>'
        VMName = '<vm-name>'
        Name = '<extension-resource-name>'
        Force = $True
    }
    Remove-AzVMCustomScriptExtension @params
    

    Om du anger fel resursnamn är StatusCodedet returnerade NoContent värdet :

    RequestId IsSuccessStatusCode StatusCode ReasonPhrase
    --------- ------------------- ---------- ------------
                             True  NoContent No Content
    

    Om du anger rätt resursnamn är StatusCodedet returnerade OK värdet :

    RequestId IsSuccessStatusCode StatusCode ReasonPhrase
    --------- ------------------- ---------- ------------
                             True         OK OK
    

Referenser

Ansvarsfriskrivning för tredje part

Microsoft tillhandahåller kontaktinformation från tredje part som hjälper dig att hitta ytterligare information om det här ämnet. Denna kontaktinformation kan ändras utan föregående meddelande. Microsoft garanterar inte att kontaktinformation från tredje part är korrekt.