繁体   English   中英

Windows EC2 用户数据未执行

[英]Windows EC2 User Data Not Executing

问题:

我们需要在 Windows AWS EC2 实例上使用用户数据执行 Powershell 脚本,以便我们可以加入和取消加入我们域的活动目录。 EC2 用户数据日志显示实例被卡在:

Ec2HandleUserData :  is currently executing. To end it kill the process with id:
 

我们尝试添加此处记录的代码行,但没有成功 任何人都可以看到做错了什么吗? 请注意,我们已注释掉日志记录,因为我们目前没有 CloudWatch 设置。 我们正在使用的脚本如下,感谢您的帮助!

<powershell>
$file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm")
New-Item $file -ItemType file
# Script parameters
[string]$SecretAD = "prod/AD"
#class Logger {
#   #----------------------------------------------
#   [string] hidden  $cwlGroup
#   [string] hidden  $cwlStream
#   [string] hidden  $sequenceToken
#   #----------------------------------------------
#   # Log Initialization
#   #----------------------------------------------
#   Logger([string] $Action) {
#       $this.cwlGroup = "/ps/boot/configuration/"
#       $this.cwlStream = "{0}/{1}/{2}" -f $env:COMPUTERNAME, $Action,
#       (Get-Date -UFormat "%Y-%m-%d_%H.%M.%S")
#       $this.sequenceToken = ""
#       #------------------------------------------
#       if ( !(Get-CWLLogGroup -LogGroupNamePrefix $this.cwlGroup) ) {
#           New-CWLLogGroup -LogGroupName $this.cwlGroup
#           Write-CWLRetentionPolicy -LogGroupName $this.cwlGroup -RetentionInDays 3
#       }
#       if ( !(Get-CWLLogStream -LogGroupName $this.cwlGroup -LogStreamNamePrefix $this.cwlStream) ) {
#           New-CWLLogStream -LogGroupName $this.cwlGroup -LogStreamName $this.cwlStream
#       }
#   }
#   #----------------------------------------
#   [void] WriteLine([string] $msg) {
#       #$logEntry = New-Object -TypeName "Amazon.CloudWatchLogs.Model.InputLogEvent"
#       #-----------------------------------------------------------
#       #$logEntry.Message = $msg
#       #$logEntry.Timestamp = (Get-Date).ToUniversalTime()
#       if ("" -eq $this.sequenceToken) {
#           # First write into empty log...
#           $this.sequenceToken = Write-CWLLogEvent -LogGroupName $this.cwlGroup `
#               -LogStreamName $this.cwlStream `
#               -LogEvent #$logEntry
#       }
#       else {
#           # Subsequent write into the log...
#           $this.sequenceToken = Write-CWLLogEvent -LogGroupName $this.cwlGroup `
#               -LogStreamName $this.cwlStream `
#               -SequenceToken $this.sequenceToken `
#               -LogEvent #$logEntry
#       }
#   }
#}
#[Logger]#$log = [Logger]::new("UserData")
#$log.WriteLine("------------------------------")
#$log.WriteLine("Log Started - V4.0")
$RunUser = 'TrustedInstaller'

Write-Output "I set the run user"

#$log.WriteLine("PowerShell session user: $RunUser")
class SDManager {
    #-------------------------------------------------------------------
    #[Logger] hidden $SDLog
    [string] hidden $GPScrShd_0_0 = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Shutdown\0\0"
    [string] hidden $GPMScrShd_0_0 = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Shutdown\0\0"
    #-------------------------------------------------------------------
    SDManager([string]$RegFilePath, [string]$SecretName) {
        #$this.SDLog = #$log
        #----------------------------------------------------------------
        [string] $SecretLine = '[string]$SecretAD    = "' + $SecretName + '"'
        #--------------- Local Variables -------------
        [string] $GPRootPath = "C:\Windows\System32\GroupPolicy"
        [string] $GPMcnPath = "C:\Windows\System32\GroupPolicy\Machine"
        [string] $GPScrPath = "C:\Windows\System32\GroupPolicy\Machine\Scripts"
        [string] $GPSShdPath = "C:\Windows\System32\GroupPolicy\Machine\Scripts\Shutdown"
        [string] $ScriptFile = [System.IO.Path]::Combine($GPSShdPath, "Shutdown-UnJoin.ps1")
        #region Shutdown script (scheduled through Local Policy)
        $ScriptBody =
        @(
            'param([string]$cntrl = "NotSet")',
            $SecretLine,
            '[string]$MachineName = $env:COMPUTERNAME',
            '#class Logger {    ',
            '#    #----------------------------------------------    ',
            '#    [string] hidden  $cwlGroup    ',
            '#    [string] hidden  $cwlStream    ',
            '#    [string] hidden  $sequenceToken    ',
            '#    #----------------------------------------------    ',
            '#    # Log Initialization    ',
            '#    #----------------------------------------------    ',
            '#    Logger([string] $Action) {    ',
            '#        $this.cwlGroup = "/ps/boot/configuration/"    ',
            '#        $this.cwlStream = "{0}/{1}/{2}" -f $env:COMPUTERNAME, $Action,    ',
            '#                                           (Get-Date -UFormat "%Y-%m-%d_%H.%M.%S")    ',
            '#        $this.sequenceToken = ""    ',
            '#        #------------------------------------------    ',
            '#        if ( !(Get-CWLLogGroup -LogGroupNamePrefix $this.cwlGroup) ) {    ',
            '#            New-CWLLogGroup -LogGroupName $this.cwlGroup    ',
            '#            Write-CWLRetentionPolicy -LogGroupName $this.cwlGroup -RetentionInDays 3    ',
            '#        }    ',
            '#        if ( !(Get-CWLLogStream -LogGroupName $this.cwlGroup -LogStreamNamePrefix $this.cwlStream) ) {    ',
            '#            New-CWLLogStream -LogGroupName $this.cwlGroup -LogStreamName $this.cwlStream    ',
            '#        }    ',
            '#    }    ',
            '#    #----------------------------------------    ',
            '#    [void] WriteLine([string] $msg) {    ',
            '#        #$logEntry = New-Object -TypeName "Amazon.CloudWatchLogs.Model.InputLogEvent"    ',
            '#        #-----------------------------------------------------------    ',
            '#        #$logEntry.Message = $msg    ',
            '#        #$logEntry.Timestamp = (Get-Date).ToUniversalTime()    ',
            '#        if ("" -eq $this.sequenceToken) {    ',
            '#            # First write into empty log...    ',
            '#            $this.sequenceToken = Write-CWLLogEvent -LogGroupName $this.cwlGroup `',
            '#                -LogStreamName $this.cwlStream `',
            '#                -LogEvent #$logEntry    ',
            '#        }    ',
            '#        else {    ',
            '#            # Subsequent write into the log...    ',
            '#            $this.sequenceToken = Write-CWLLogEvent -LogGroupName $this.cwlGroup `',
            '#                -LogStreamName $this.cwlStream `',
            '#                -SequenceToken $this.sequenceToken `',
            '#                -LogEvent #$logEntry    ',
            '#        }    ',
            '#    }    ',
            '#}    ',
            '#[Logger]#$log = [Logger]::new("UnJoin")',
            '#$log.WriteLine("-----------------------------------------")',
            '#$log.WriteLine("Log Started")',
            'if ($cntrl -ne "run") ',
            '    { ',
            '    #$log.WriteLine("Script param <" + $cntrl + "> not set to <run> - script terminated") ',
            '    return',
            '    }',
            '$compSys = Get-WmiObject -Class Win32_ComputerSystem',
            'if ( -Not ($compSys.PartOfDomain))',
            '    {',
            '    #$log.WriteLine("Not member of a domain - terminating script")',
            '    return',
            '    }',
            '$RSAT = (Get-WindowsFeature RSAT-AD-PowerShell)',
            'if ( $RSAT -eq $null -or (-Not $RSAT.Installed) )',
            '    {',
            '    #$log.WriteLine("<RSAT-AD-PowerShell> feature not found - terminating script")',
            '    return',
            '    }',
            '#$log.WriteLine("Removing machine <" +$MachineName + "> from Domain <" + $compSys.Domain + ">")',
            '#$log.WriteLine("Reading Secret <" + $SecretAD + ">")',
            #'Import-Module AWSPowerShell',
            #'try { $SecretObj = (Get-SECSecretValue -SecretId $SecretAD) }',
            #'catch ',
            #'    { ',
            #'    #$log.WriteLine("Could not load secret <" + $SecretAD + "> - terminating execution")',
            #'    return ',
            #'    }',
            #'[PSCustomObject]$Secret = ($SecretObj.SecretString  | ConvertFrom-Json)',
            '$password   = "<password>"',
            '$username   = "<username>"',
            '$credential = New-Object System.Management.Automation.PSCredential($username,$password)',
            'import-module ActiveDirectory',
            '$DCHostName = (Get-ADDomainController -Discover).HostName',
            '#$log.WriteLine("Using Account <" + $username + ">")',
            '#$log.WriteLine("Using Domain Controller <" + $DCHostName + ">")',
            'Remove-Computer -WorkgroupName "WORKGROUP" -UnjoinDomainCredential $credential -Force -Confirm:$false ',
            'Remove-ADComputer -Identity $MachineName -Credential $credential -Server "$DCHostName" -Confirm:$false ',
            '#$log.WriteLine("Machine <" +$MachineName + "> removed from Domain <" + $compSys.Domain + ">")'
        )
        #$this.SDLog.WriteLine("Constracting artifacts required for domain UnJoin")
        #----------------------------------------------------------------
    Write-Output "I created SDManager class"

        try {
            if (!(Test-Path -Path $GPRootPath -pathType container))
            { New-Item -ItemType directory -Path $GPRootPath }
            if (!(Test-Path -Path $GPMcnPath -pathType container))
            { New-Item -ItemType directory -Path $GPMcnPath }
            if (!(Test-Path -Path $GPScrPath -pathType container))
            { New-Item -ItemType directory -Path $GPScrPath }
            if (!(Test-Path -Path $GPSShdPath -pathType container))
            { New-Item -ItemType directory -Path $GPSShdPath }
        }
        catch {
            #$this.SDLog.WriteLine("Failure creating UnJoin script directory!" )
            #$this.SDLog.WriteLine($_)
            Write-Output  "hello"
        }
        #----------------------------------------
        try {
            Set-Content $ScriptFile -Value $ScriptBody
        }
        catch {
            #$this.SDLog.WriteLine("Failure saving UnJoin script!" )
            #$this.SDLog.WriteLine($_)
            Write-Output  "hello"
        }
        #----------------------------------------
        
# UPDATE WINDOWS REGISTRY AND CREATE A SHUTDOWN TASK        
        
        $RegistryScript =
        @(
            'Windows Registry Editor Version 5.00',
            '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts]',
            '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Shutdown]',
            '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Shutdown\0]',
            '"GPO-ID"="LocalGPO"',
            '"SOM-ID"="Local"',
            '"FileSysPath"="C:\\Windows\\System32\\GroupPolicy\\Machine"',
            '"DisplayName"="Local Group Policy"',
            '"GPOName"="Local Group Policy"',
            '"PSScriptOrder"=dword:00000001',
            '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Shutdown\0\0]',
            '"Script"="Shutdown-UnJoin.ps1"',
            '"Parameters"=""',
            '"IsPowershell"=dword:00000001',
            '"ExecTime"=hex(b):00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00',
            '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup]',
            '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts]',
            '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Shutdown]',
            '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Shutdown\0]',
            '"GPO-ID"="LocalGPO"',
            '"SOM-ID"="Local"',
            '"FileSysPath"="C:\\Windows\\System32\\GroupPolicy\\Machine"',
            '"DisplayName"="Local Group Policy"',
            '"GPOName"="Local Group Policy"',
            '"PSScriptOrder"=dword:00000001',
            '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Shutdown\0\0]',
            '"Script"="Shutdown-UnJoin.ps1"',
            '"Parameters"=""',
            '"ExecTime"=hex(b):00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00',
            '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup]'
        )
        Write-Output "I created the registry script."

        try {
            [string] $RegistryFile = [System.IO.Path]::Combine($RegFilePath, "OnShutdown.reg")
            Set-Content $RegistryFile -Value $RegistryScript
            &regedit.exe /S "$RegistryFile"
        }
        catch {
            #$this.SDLog.WriteLine("Failure creating policy entry in Registry!" )
            #$this.SDLog.WriteLine($_)
            Write-Output "hello"
        }
    }

#DISABLE UNJOIN AND ENABLE JOIN FOR THE FIRST RUN
    
    #----------------------------------------
    [void] DisableUnJoin() {
        try {
            Set-ItemProperty -Path $this.GPScrShd_0_0  -Name "Parameters" -Value "ignore"
            Set-ItemProperty -Path $this.GPMScrShd_0_0 -Name "Parameters" -Value "ignore"
            &gpupdate /Target:computer /Wait:0
        }
        catch {
            #$this.SDLog.WriteLine("Failure in <DisableUnjoin> function!" )
            #$this.SDLog.WriteLine($_)
            Write-Output  "hello"
        }
    }
    #----------------------------------------
    [void] EnableUnJoin() {
        try {
            Set-ItemProperty -Path $this.GPScrShd_0_0  -Name "Parameters" -Value "run"
            Set-ItemProperty -Path $this.GPMScrShd_0_0 -Name "Parameters" -Value "run"
            &gpupdate /Target:computer /Wait:0
        }
        catch {
            #$this.SDLog.WriteLine("Failure in <EnableUnjoin> function!" )
            #$this.SDLog.WriteLine($_)
            Write-Output "hello"
        }
    }
}
Write-Output "I created the the join and unjoin functions"
# GET SECRETS

#[SDManager]$sdm = [SDManager]::new(#$log, "C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts", $SecretAD)
##$log.WriteLine("Loading Secret <" + $SecretAD + ">")
#Import-Module AWSPowerShell
#try { $SecretObj = (Get-SECSecretValue -SecretId $SecretAD) }
#catch {
#   #$log.WriteLine("Could not load secret <" + $SecretAD + "> - terminating execution")
#   return
#}
#[PSCustomObject]$Secret = ($SecretObj.SecretString  | ConvertFrom-Json)
##$log.WriteLine("Domain (from Secret): <" + $domain + ">")



# Verify domain membership

#IF ALREADY MEMBER OF DOMAIN 

$compSys = Get-WmiObject -Class Win32_ComputerSystem
#------------------------------------------------------------------------------
if ( ($compSys.PartOfDomain) -and ($compSys.Domain -eq $domain)) {
    #$log.WriteLine("Already member of: <" + $compSys.Domain + "> - Verifying RSAT Status")
    
    #CHECK IF RSTAT IS INSTALLED
    
    $RSAT = (Get-WindowsFeature RSAT-AD-PowerShell)
    if ($null -eq $RSAT) {
        #$log.WriteLine("<RSAT-AD-PowerShell> feature not found - terminating script")
        return
    }
    
    #ENABLE ON SHUT DOWN & INSTALL RSTAT
    
    #$log.WriteLine("Enable OnShutdown task to un-join Domain")
    $sdm.EnableUnJoin()
    if ( (-Not $RSAT.Installed) -and ($RSAT.InstallState -eq "Available") ) {
        #$log.WriteLine("Installing <RSAT-AD-PowerShell> feature")
        Install-WindowsFeature RSAT-AD-PowerShell
    }
    #$log.WriteLine("Terminating script - ")
    return
}

# IF NOT MEMBER OF DOMAIN THEN JOIN AND RESTART

# Performing Domain Join
#$log.WriteLine("Domain Join required")
#$log.WriteLine("Disable OnShutdown task to avoid reboot loop")
$sdm.DisableUnJoin()
$password = "<password>"
$username = "<username>"
$domain = "<domain>"
$credential = New-Object System.Management.Automation.PSCredential($username, $password)
#$log.WriteLine("Attempting to join domain <" + $domain + ">")
Add-Computer -DomainName $domain -Credential $credential -Restart -Force
#$log.WriteLine("Requesting restart...")

Write-Output "I joined or unjoined the domain friends."
#------------------------------------------------------------------------------
</powershell>
<persist>true</persist>

你找到答案了吗? 我相信您的内联脚本太长而无法在用户数据中执行。 您可能会在这里遇到问题: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-add-user-data.html

当我遇到这个问题时,我发现最好将脚本上传到 S3,允许 EC2 实例 RO 通过 EC2 实例配置文件访问 S3 存储桶,然后从存储桶中提取并在用户数据中运行脚本。

喂!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM