-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathWinCloudInit.psm1
95 lines (87 loc) · 3.31 KB
/
WinCloudInit.psm1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
function Set-WinCloudInit {
param(
[switch] $Enabled,
[ValidateRange(0,99)]
[int] $State,
[pscredential] $Credential
)
Set-Content $PSScriptRoot\state $State
if ($PSBoundParameters.ContainsKey('Enabled')) {
if ($Enabled) {
Set-WinCloudInit -Enabled:$false
if (-not $Credential) {
$Credential = Get-Credential -UserName $env:USERNAME -Message 'Specify credential'
}
$user = $Credential.UserName
$password = $Credential.GetNetworkCredential().Password
$command = 'powershell -Command Start-WinCloudInit'
schtasks /Create /TN 'WinCloudInit' /RU $user /RP $password /TR $command /SC ONSTART
} else {
if (schtasks | Select-String WinCloudInit) {
schtasks /Delete /TN 'WinCloudInit' /F
}
}
} elseif ($Credential.UserName -eq 'SYSTEM') {
schtasks /Change /TN 'WinCloudInit' /RU 'SYSTEM'
}
}
function Start-WinCloudInit {
[CmdletBinding()]
param()
$Log = Join-Path C:\Windows\Temp "WinCloudInit-$((Get-Date).ToString('MM-dd-yy')).log"
"Starting WinCloudInit $(Get-Date)" >> $Log
'Searching for cloud-config.json on floppy/cdrom' >> $Log
$Found = $false
2,5 | % {
if ($ConfigDrive = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType = $_" -Property DeviceID) {
$ConfigPath = Join-Path $ConfigDrive.DeviceID 'cloud-config.json'
if (Test-Path $ConfigPath) { $Found = $ConfigPath; return }
}
}
if (-not $Found) {
'Searching for cloud-config.json on local drive' >> $Log
$LocalPath = 'C:\WinCloudInit\cloud-config.json'
if (Test-Path $LocalPath) { $Found = $LocalPath }
}
if ($Found) {
"Found in $Found" >> $Log
$Config = Get-Content $Found -Raw | ConvertFrom-Json |
Add-Member -MemberType NoteProperty -Name _Path -Value (Split-Path $Found) -TypeName string -Force -PassThru
mkdir C:\WinCloudInit\ -ea SilentlyContinue
Copy-Item $Found "C:\WinCloudInit\_cloud-config.json" -Force
} else {
$Msg = 'No config source found'
$Msg >> $Log
throw $Msg
}
# state file contains last executed plugin number (for reboot handling)
'Reading <state> file' >> $Log
$StatePath = "$PSScriptRoot\state"
try {
if (-not (Test-Path $StatePath)) {
New-Item -Path $StatePath -ItemType File
}
$State = [int](Get-Content $StatePath)
"State is $State" >> $Log
} catch {
$Msg = 'Invalid state file content'
$Msg >> $Log
throw $Msg
}
'Running plugins:' >> $Log
Get-ChildItem $PSScriptRoot\plugins | Sort Name |
? { ($_.Name.Split('-')[0] -as [int]) -gt $State } -pv Plugin | % {
try {
"Executing $($Plugin.Name)" >> $Log
$Output = & $Plugin.FullName -Config $Config -Verbose 4>> $Log
} catch {
$Msg = "Error during $($Plugin.Name) execution"
($_ | Out-String) >> $Log
throw $Msg
}
$Plugin.Name.Split('-')[0] > $StatePath
if (($Output | Select -Last 1) -eq 'reboot') { break } # exit function, continue after reboot
}
'Disabling WinCloudInit' >> $Log
Set-WinCloudInit -Enabled:$false
}