# Get jq to parse JSON content [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 (New-Object System.Net.WebClient).DownloadFile("https://github.com/stedolan/jq/releases/download/jq-1.6/jq-win64.exe", "$pwd\jq.exe") # Retrieve NS config from CustomData $customdata = cat $env:systemdrive\AzureData\CustomData.bin # Parse $rmurl = echo $customdata | .\jq.exe '.rmurl' -r $credentials = echo $customdata | .\jq.exe '.credentials' -r $nodesourcename = echo $customdata | .\jq.exe '.nodesourcename' -r $storageaccount = echo $customdata | .\jq.exe '.storageaccount' -r $saskey = echo $customdata | .\jq.exe '.saskey' -r $usercustomscripturl = echo $customdata | .\jq.exe '.usercustomscripturl' -r $externalstorageaccount = echo $customdata | .\jq.exe '.externalstorageaccount' -r $adminUsername = echo $customdata | .\jq.exe '.username' -r $adminPassword = echo $customdata | .\jq.exe '.password' -r $jvmParameters = echo $customdata | .\jq.exe '.jvmparameters' -r $nodePreCommand = echo $customdata | .\jq.exe '.nodeprecommand' -r | % {$_.Replace("\n","`n")} | % {$_ + "`n"} # Install JRE # Create config file for silent install $text = ' INSTALL_SILENT=Enable AUTO_UPDATE=Enable SPONSORS=Disable REMOVEOUTOFDATEJRES=1 ' $text | Set-Content "$pwd\jreinstall.cfg" # Download executable (New-Object System.Net.WebClient).DownloadFile("https://ci-materials.s3.amazonaws.com/Latest_jre/jre-8u382b05-windows-x64.zip", "c:\jre.zip"); Expand-Archive c:\jre.zip -DestinationPath c:\; Rename-Item c:\jre1.8.0_382b05 c:\jre # Execute User Script if provided if (-not ([string]::IsNullOrEmpty($usercustomscripturl))) { (New-Object System.Net.WebClient).DownloadFile($usercustomscripturl, "$pwd\UserScript.ps1") .\UserScript.ps1 } # Get node.jar (New-Object System.Net.WebClient).DownloadFile("https://$storageaccount.blob.core.windows.net/nodefiles/node.jar?$saskey", "$pwd\node.jar") # Get parameters from the queue $timeout = 300 $queueMessage = Invoke-WebRequest -Method Get -Headers @{'Accept' = 'application/xml'} -Uri "https://$storageaccount.queue.core.windows.net/nodeconfig/messages?visibilitytimeout=$timeout&$saskey" -UseBasicParsing [xml]$queue = [xml]$queueMessage.Content.substring(3) # Remove unknown chars from content $msgId = $queue.QueueMessagesList.QueueMessage.MessageId $popReceipt = [uri]::EscapeDataString($queue.QueueMessagesList.QueueMessage.PopReceipt) $msgText = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($queue.QueueMessagesList.QueueMessage.MessageText)) $nodebasename = echo $msgText | .\jq.exe '.nodebasename' -r $nodeinstances = echo $msgText | .\jq.exe '.nodeinstances' -r # Immediately delete the message from the queue Invoke-RestMethod -Method Delete -Uri "https://$storageaccount.queue.core.windows.net/nodeconfig/messages/${msgId}?popreceipt=$popReceipt&$saskey" # Retrieve instance metadata $headers = @{ 'Metadata' = 'true' } $metadata = Invoke-RestMethod -Method Get -Headers $headers -Uri "http://169.254.169.254/metadata/instance/compute?api-version=2017-12-01" $instancename = echo $metadata | ConvertTo-Json | .\jq.exe '.name' -r $instanceid = echo $instancename | %{ -join $_[$_.Length..0] } | %{ $_.Split('_')[0] } | %{ -join $_[$_.Length..0] } # Update Azure table $body = @{ 'PartitionKey' = $env:computername 'RowKey' = $nodebasename 'NodesCount' = $nodeinstances 'InstanceId' = $instanceid } | ConvertTo-Json $headers = @{ 'Content-Type' = 'application/json' 'Accept' = 'application/json' } Invoke-RestMethod -Method Post -Headers $headers -Body $body -Uri "https://$storageaccount.table.core.windows.net/nodesperhost?$saskey" # Create Firewall Rules New-NetFirewallRule -DisplayName "Inbound_PNP" -Direction Inbound -LocalPort 64738 -Protocol TCP -Action Allow New-NetFirewallRule -DisplayName "Outbound_PNP" -Direction Outbound -LocalPort 64738 -Protocol TCP -Action Allow New-NetFirewallRule -DisplayName "Outbound_PAMR" -Direction Outbound -LocalPort 33647 -Protocol TCP -Action Allow New-NetFirewallRule -DisplayName "Outbound_SSH" -Direction Outbound -LocalPort 22 -Protocol TCP -Action Allow New-NetFirewallRule -DisplayName "Outbound_HTTP" -Direction Outbound -LocalPort 8080 -Protocol TCP -Action Allow New-NetFirewallRule -DisplayName "Outbound_HTTPS" -Direction Outbound -LocalPort 8443 -Protocol TCP -Action Allow # Create and run a service for a different user by using nssm # (New-Object System.Net.WebClient).DownloadFile("http://nssm.cc/release/nssm-2.24.zip", "$pwd\nssm-2.24.zip") (New-Object System.Net.WebClient).DownloadFile("http://www.activeeon.com/public_content/tools/nssm/nssm-2.24.zip", "$pwd\nssm-2.24.zip") Add-Type -Assembly "system.io.compression.filesystem" [io.compression.zipfile]::ExtractToDirectory("$pwd\nssm-2.24.zip","$pwd") rm -force .\nssm-2.24.zip -confirm:$false Set-Content $pwd\proactive-node.bat "${nodePreCommand}c:\jre\bin\java -jar $pwd\node.jar $jvmParameters -v $credentials -w $nodeinstances -r $rmurl -n $nodebasename -s $nodesourcename" -Encoding ASCII .\nssm-2.24\win64\nssm.exe install ProactiveNode $pwd\proactive-node.bat .\nssm-2.24\win64\nssm.exe set ProactiveNode AppDirectory $pwd .\nssm-2.24\win64\nssm.exe set ProactiveNode ObjectName ".\$adminUsername" "$adminPassword" .\nssm-2.24\win64\nssm.exe set ProactiveNode Start SERVICE_AUTO_START .\nssm-2.24\win64\nssm.exe start ProactiveNode