Question: How do I troubleshoot helper scripts that won't bootstrap in a CloudFormation stack with Windows instances?

My helper scripts won't bootstrap in an AWS CloudFormation stack with Microsoft Windows instances. How do I resolve this issue?Short descriptionIn a Windows instance, UserData that runs as a child process of EC2ConfigService invokes cfn-init.exe. Certain steps that cfn-init.exe performs might require a system reboot.For example, you must reboot the system if you rename a computer, or join a computer to a domain. After the system reboots, cfn-init continues to run the rest of the configurations that remain in AWS::CloudFormation::Init with the help of C:\cfn\cfn-init\resume_db.json.For helper scripts that don't run after rebooting the Windows instance, complete the steps in the Troubleshoot bootstrapping issues section.If you receive the following error, then you might have issues with cfn-signal:"Received 0 conditions when expecting X or Failed to receive X resource signal(s) within the specified duration"To resolve the preceding error, complete the steps in the Troubleshoot cfn-signal issues section.For both issues, complete the steps in the Follow the best practices for using a Windows operating system with CloudFormation section.

ResolutionTroubleshoot bootstrapping issuesIf your script doesn't run after reboot, then complete the following steps:1.    In the commands section of your cfn-init configuration set, confirm that waitAfterCompletion is set to forever. For example:"commands": { "0-restart": { "command": "powershell.exe -Command Restart-Computer", "waitAfterCompletion": "forever" } }Note: The forever value directs cfn-init to exit and resume only after the reboot is complete. For more information, see AWS::CloudFormation::Init.2.    Check the following logs for errors:Amazon Elastic Compute Cloud (Amazon EC2) configuration log at C:\Program Files\Amazon\Ec2ConfigService\Logs\Ec2ConfigLog.txt (versions before Windows 2016)Amazon EC2 configuration log at *C:\ProgramData\Amazon\EC2-Windows\Launch\Log* (Windows 2016 and later)cfn-init log at C:\cfn\log\cfn-init.logWindows Event logs at C:\Windows\System32\winevt\logsTroubleshoot cfn-signal issues1.    Confirm that the cfn-signal is configured correctly.Important: Use -e $lastexitcode in PowerShell scripts, and use -e %ERRORLEVEL% for Windows cmd.exe scripts.For PowerShell scripts in UserData, use the following tags:<powershell></powershell>Example PowerShell script:UserData:        Fn::Base64:          Fn::Sub : |            <powershell>            $LASTEXITCODE=0            echo Current date and time >> C:\Temp\test.log            echo %DATE% %TIME% >> C:\Temp\test.log            cfn-init.exe -s ${AWS::StackId} -r SInstance --region ${AWS::Region}            New-Item -Path "C:\" -Name userdata -ItemType directory            cfn-signal.exe -e $LASTEXITCODE --stack ${AWS::StackId} --resource WindowsInstance --region ${AWS::Region}            </powershell>For cmd.exe scripts in UserData, use the following tags:<script></script>Example cmd.exe script:UserData:  Fn::Base64: !Sub |    <script>    cfn-init.exe -v -s ${AWS::StackId} -r WindowsInstance --configsets ascending --region ${AWS::Region}    cfn-signal.exe -e %ERRORLEVEL% --stack ${AWS::StackId} --resource WindowsInstance --region ${AWS::Region}    </script>2.    Increase the Timeout of the WaitCondition to 1800/3600 seconds based on the example of bootstrapping a Windows stack.Note: Step 2 is necessary because Windows instances usually take longer than Linux instances to complete their initial boot process.3.    If you're using a custom Amazon Machine Image (AMI), then you must use Sysprep to create the AMI before you start. If you don't use Sysprep, then you might experience metadata issues and get the following error in the user data log for metadata:Failed to get metadata: The result from http://169.254.169.254/latest/user-data was emptyUnable to execute userdata: Userdata was not providedFollow the best practices for using a Windows operating system with CloudFormationInclude $ErrorActionPreference = "Stop" at the top of your PowerShell scripts to catch exceptions.When you refer to a Windows path in your CloudFormation template, you must add a forward slash (/) at the beginning of the path. For example:"commands" : {  "1-extract" : {    "command" : "C:\\SharePoint\\SharePointFoundation2010.exe /extract:C:\\SharePoint\\SPF2010 /quiet /log:C:\\SharePoint\\SharePointFoundation2010-extract.log"  }For Windows stacks, you must base64-encode the WaitCondition handle URL again. For example:cfn-signal.exe -e %ERRORLEVEL% ", { "Fn::Base64" : { "Ref" : "SharePointFoundationWaitHandle" }}, "\n"