-
Notifications
You must be signed in to change notification settings - Fork 0
/
make_unattend_iso.ps1
141 lines (125 loc) · 6.04 KB
/
make_unattend_iso.ps1
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# This builds the unattend ISOs needed for Generation 2 VMs with Hyper-V
$isoList = @(
@{
FileName="./iso/windows_server_2016_unattend.iso";
Files=@(
"./sysprep_answer_files/2016_uefi/Autounattend.xml",
"./scripts/disable-winrm.ps1",
"./scripts/enable-winrm.ps1",
"./scripts/sysprep.bat",
"./scripts/unattend.xml"
)
},
@{
FileName="./iso/windows_server_2012r2_unattend.iso";
Files=@(
"./sysprep_answer_files/2012r2_uefi/Autounattend.xml",
"./scripts/disable-winrm.ps1",
"./scripts/enable-winrm.ps1",
"./scripts/sysprep.bat",
"./scripts/unattend.xml"
)
},
@{
FileName="./iso/windows_server_2019_unattend.iso";
Files=@(
"./sysprep_answer_files/2019_uefi/Autounattend.xml",
"./scripts/disable-winrm.ps1",
"./scripts/enable-winrm.ps1",
"./scripts/sysprep.bat",
"./scripts/unattend.xml"
)
}
)
# FROM https://gallery.technet.microsoft.com/scriptcenter/New-ISOFile-function-a8deeffd
# This probably won't work on Windows Server Core, so may need a different solution later
function New-IsoFile
{
<#
.Synopsis
Creates a new .iso file
.Description
The New-IsoFile cmdlet creates a new .iso file containing content from chosen folders
.Example
New-IsoFile "c:\tools","c:\Downloads\utils"
This command creates a .iso file in $env:temp folder (default location) that contains c:\tools and c:\downloads\utils folders. The folders themselves are included at the root of the .iso image.
.Example
New-IsoFile -FromClipboard -Verbose
Before running this command, select and copy (Ctrl-C) files/folders in Explorer first.
.Example
dir c:\WinPE | New-IsoFile -Path c:\temp\WinPE.iso -BootFile "${env:ProgramFiles(x86)}\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\efisys.bin" -Media DVDPLUSR -Title "WinPE"
This command creates a bootable .iso file containing the content from c:\WinPE folder, but the folder itself isn't included. Boot file etfsboot.com can be found in Windows ADK. Refer to IMAPI_MEDIA_PHYSICAL_TYPE enumeration for possible media types: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366217(v=vs.85).aspx
.Notes
NAME: New-IsoFile
AUTHOR: Chris Wu
LASTEDIT: 03/23/2016 14:46:50
#>
[CmdletBinding(DefaultParameterSetName='Source')]Param(
[parameter(Position=1,Mandatory=$true,ValueFromPipeline=$true, ParameterSetName='Source')]$Source,
[parameter(Position=2)][string]$Path = "$env:temp\$((Get-Date).ToString('yyyyMMdd-HHmmss.ffff')).iso",
[ValidateScript({Test-Path -LiteralPath $_ -PathType Leaf})][string]$BootFile = $null,
[ValidateSet('CDR','CDRW','DVDRAM','DVDPLUSR','DVDPLUSRW','DVDPLUSR_DUALLAYER','DVDDASHR','DVDDASHRW','DVDDASHR_DUALLAYER','DISK','DVDPLUSRW_DUALLAYER','BDR','BDRE')][string] $Media = 'DVDPLUSRW_DUALLAYER',
[string]$Title = (Get-Date).ToString("yyyyMMdd-HHmmss.ffff"),
[switch]$Force,
[parameter(ParameterSetName='Clipboard')][switch]$FromClipboard
)
Begin {
($cp = new-object System.CodeDom.Compiler.CompilerParameters).CompilerOptions = '/unsafe'
if (!('ISOFile' -as [type])) {
Add-Type -CompilerParameters $cp -TypeDefinition @'
public class ISOFile
{
public unsafe static void Create(string Path, object Stream, int BlockSize, int TotalBlocks)
{
int bytes = 0;
byte[] buf = new byte[BlockSize];
var ptr = (System.IntPtr)(&bytes);
var o = System.IO.File.OpenWrite(Path);
var i = Stream as System.Runtime.InteropServices.ComTypes.IStream;
if (o != null) {
while (TotalBlocks-- > 0) {
i.Read(buf, BlockSize, ptr); o.Write(buf, 0, bytes);
}
o.Flush(); o.Close();
}
}
}
'@
}
if ($BootFile) {
if('BDR','BDRE' -contains $Media) { Write-Warning "Bootable image doesn't seem to work with media type $Media" }
($Stream = New-Object -ComObject ADODB.Stream -Property @{Type=1}).Open() # adFileTypeBinary
$Stream.LoadFromFile((Get-Item -LiteralPath $BootFile).Fullname)
($Boot = New-Object -ComObject IMAPI2FS.BootOptions).AssignBootImage($Stream)
}
$MediaType = @('UNKNOWN','CDROM','CDR','CDRW','DVDROM','DVDRAM','DVDPLUSR','DVDPLUSRW','DVDPLUSR_DUALLAYER','DVDDASHR','DVDDASHRW','DVDDASHR_DUALLAYER','DISK','DVDPLUSRW_DUALLAYER','HDDVDROM','HDDVDR','HDDVDRAM','BDROM','BDR','BDRE')
Write-Verbose -Message "Selected media type is $Media with value $($MediaType.IndexOf($Media))"
($Image = New-Object -com IMAPI2FS.MsftFileSystemImage -Property @{VolumeName=$Title}).ChooseImageDefaultsForMediaType($MediaType.IndexOf($Media))
if (!($Target = New-Item -Path $Path -ItemType File -Force:$Force -ErrorAction SilentlyContinue)) { Write-Error -Message "Cannot create file $Path. Use -Force parameter to overwrite if the target file already exists."; break }
}
Process {
if($FromClipboard) {
if($PSVersionTable.PSVersion.Major -lt 5) { Write-Error -Message 'The -FromClipboard parameter is only supported on PowerShell v5 or higher'; break }
$Source = Get-Clipboard -Format FileDropList
}
foreach($item in $Source) {
if($item -isnot [System.IO.FileInfo] -and $item -isnot [System.IO.DirectoryInfo]) {
$item = Get-Item -LiteralPath $item
}
if($item) {
Write-Verbose -Message "Adding item to the target image: $($item.FullName)"
try { $Image.Root.AddTree($item.FullName, $true) } catch { Write-Error -Message ($_.Exception.Message.Trim() + ' Try a different media type.') }
}
}
}
End {
if ($Boot) { $Image.BootImageOptions=$Boot }
$Result = $Image.CreateResultImage()
[ISOFile]::Create($Target.FullName,$Result.ImageStream,$Result.BlockSize,$Result.TotalBlocks)
Write-Verbose -Message "Target image ($($Target.FullName)) has been created"
$Target
}
}
$isoList | foreach-object {
New-IsoFile -Path $_.FileName -Source $_.Files -Force:$true -Media "CDR"
}