Matt
Matt

Reputation: 33

Im creating a VM using terraform code in GCP. I would like to inject a script that runs when the vm is created upon startup

Here is what I have, its not working:

metadata_startup_script = <<-SCRIPT
<powershell>
# Set execution policy to RemoteSigned
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force

# PowerShell script to rename the computer
$newName = "mktestcomputer$($count.index + 1)" # Set your desired computer name here
$computerInfo = Get-WmiObject Win32_ComputerSystem
$computerInfo.Rename($newName)
Restart-Computer -Force
</powershell>
SCRIPT

It's being executed on Win2022 OS, but it does not run. The VMs both get created with disks, but do not get renamed. Any ideas how to get that working?

Upvotes: 0

Views: 175

Answers (2)

KarlV
KarlV

Reputation: 1

Something I ran into that might help:

"windows-startup-script-ps1" creates a script that runs on every subsequent reboot.

According to the GCP docs what you want is: "sysprep-specialize-script-ps1" It will run on the first boot and never again.

Reference: https://cloud.google.com/compute/docs/instances/startup-scripts/windows

This is how I use it - I also don't like to clutter up my TF with raw scripts so I use a file reference:

metadata = {
    
 # Set the Timezone
 "user-data" = <<EOF
 powershell -Command "tzutil /s 'Pacific Standard Time'" 
 EOF
    
 # Windows post install config
 enable-windows-automatic-updates    = "true"
 sysprep-specialize-script-ps1       = file("../../scripts/windows-startup-config.ps1")

}

Upvotes: 0

Matt
Matt

Reputation: 33

Thanks all. Turns out there were a few problems there. Here is what Im using now that works great. It renames and joins the domain, and sets the TZ and logs as well. I run this on my target to create the PW file:

alternate method of securing passwords

# Pre-generate a key and save it for later use.
$Key = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | out-file c:\Windows\Startup\aes.key
# Copy the key file into remote computer

# Get a credential and use pre-generated key for encryption
# Save the encrypted password on a file
(get-credential).Password | ConvertFrom-SecureString -key (get-content 
c:\Windows\Startup\aes.key) | set-content "c:\Windows\Startup\password.txt"

and here is the metadata:

metadata = {
  windows-startup-script-ps1 = <<-script
  # PowerShell script to rename the computer and join AD
  Start-Transcript -path c:\Windows\Startup\output.txt -append
  # Check if the marker file exists
  if (Test-Path -Path "C:\Windows\Startup\Markerfile.txt") {
    exit
  } else {
  $password = Get-Content C:\Windows\Startup\password.txt | ConvertTo-SecureString -Key (Get-Content C:\Windows\Startup\aes.key)
  $userName = "some username here"
  $credential = New-Object System.Management.Automation.PsCredential($username,$password)
  $domain = "mydomain.com"
  Add-Computer -DomainName $domain -Credential $Credential -NewName "MYIMAGE" -Force -Restart
  Set-TimeZone -Name 'US Eastern Standard Time' -PassThru
  # Create a marker file to indicate that the script has run once
  New-Item -ItemType File -Path "C:\Windows\Startup\Markerfile.txt"
  }
  Stop-Transcript
  script

}

Upvotes: 0

Related Questions