Public/Get-OSDWinPE.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<#
.SYNOPSIS
Common WinPE Commands using wpeutil and Microsoft DaRT RemoteRecovery
 
.DESCRIPTION
Common WinPE Commands using wpeutil and Microsoft DaRT RemoteRecovery
 
.LINK
https://osd.osdeploy.com/module/functions/get-osdwinpe
 
.NOTES
19.10.1 David Segura @SeguraOSD
#>

function Get-OSDWinPE {
    [CmdletBinding()]
    Param (
        #PowerShell Module Parameter
        #Searches all Drives for <drive>:\Modules directory
        #Copies Modules content to System32 $PSModulesPath
        [Alias('Modules')]
        [switch]$AddModules,

        #PowerShell Module Parameter
        #Imports a PowerShell Module by Name
        #PowerShell Module must exist in $PSModulePath
        [Alias('Import')]
        [string[]]$ImportModule,

        #PowerShell Script Parameter
        #Searches all Drives for <drive>:\$ImportModule file
        #Calls <drive>:\$ImportModule in the current PS Session
        [Alias('Script')]
        [string]$CallScript,

        #wpeutil InitializeNetwork
        #Initializes network components and drivers and sets the computer name to a randomly-chosen value
        [Alias('Network')]
        [switch]$InitializeNetwork,

        #wpeutil InitializeNetwork /NoWait
        #Initializes network components and drivers and sets the computer name to a randomly-chosen value
        #The /NoWait option will skip the time where your PC would otherwise wait to acquire an IP address
        #If you don't use /NoWait, Windows PE will wait to acquire an address before it finishes loading your WinPE session
        #/NoWait is helpful for environments that don't use DHCP
        [Alias('NetworkNoWait')]
        [switch]$InitializeNetworkNoWait,

        #wpeutil WaitForNetwork
        #Waits for the network card to be initialized
        #Use this command when creating scripts to make sure that the network card has been fully initialized before continuing
        [Alias('WaitNetwork')]
        [switch]$WaitForNetwork,

        #wpeutil WaitForRemovableStorage
        #During the Windows PE startup sequence, this command will block startup until the removable storage devices, such as USB hard drives, are initialized
        [Alias('WaitUSB')]
        [switch]$WaitForRemovableStorage,

        #wpeutil DisableFirewall
        #Disables the Firewall
        [Alias('Disable')]
        [switch]$DisableFirewall,

        #wpeutil UpdateBootInfo
        #Populates the registry with information about how Windows PE boots
        #After you run this command, query the registry. For example:
        #reg query HKLM\System\CurrentControlSet\Control /v PEBootType
        #The results of this operation might change after loading additional driver support.
        #To determine where Windows PE is booted from, examine the following:
        # PEBootType: Error, Flat, Remote, Ramdisk:SourceIdentified Ramdisk:SourceUnidentified, Ramdisk:OpticalDrive
        # PEBootTypeErrorCode: HRESULT code
        # PEBootServerName: Windows Deployment Services server name
        # PEBootServerAddr: Windows Deployment Services server IP address
        # PEBootRamdiskSourceDrive: Source drive letter, if available.
        # PEFirmwareType: Firmware boot mode: 0x1 for BIOS, 0x2 for UEFI.
        #If you are not booting Windows Deployment Services, the best way to determine where Windows PE booted from is to first check for PEBootRamdiskSourceDrive registry key
        #If it is not present, scan the drives of the correct PEBootType and look for some kind of tag file that identifies the boot drive
        [Alias('Update')]
        [switch]$UpdateBootInfo,

        #RemoteRecovery.exe -nomessage
        #Microsoft Diagnostic and Recovery Toolset Remote Recovery
        [Alias('Remote')]
        [switch]$RemoteRecovery,

        #wpeutil Reboot
        #Reboots the computer
        [switch]$Reboot,
        
        #wpeutil Shutdown
        #Shutdown the computer
        [switch]$Shutdown
    )
    #======================================================================================================
    #    IsWinPE
    #======================================================================================================
    if (Get-OSDGather -Property IsWinPE) {Write-Verbose 'OSDWinPE: WinPE is running'}
    else {Write-Warning 'OSDWinPE: This function requires WinPE'; Break}
    #======================================================================================================
    #    Increase the Console Screen Buffer size
    #======================================================================================================
    if (!(Test-Path "HKCU:\Console")) {
        Write-Verbose "OSDWinPE: Increase Console Screen Buffer"
        New-Item -Path "HKCU:\Console" -Force | Out-Null
        New-ItemProperty -Path HKCU:\Console ScreenBufferSize -Value 589889656 -PropertyType DWORD -Force | Out-Null
    }
    #======================================================================================================
    #    CallScript
    #======================================================================================================
    if ($CallScript) {
        $OSDCallScripts = @()

        #Get all available Drives
        $OSDSearchDrives = Get-PSDrive -PSProvider 'FileSystem'

        foreach ($OSDSearchDrive in $OSDSearchDrives) {
            $FoundCallScript = "$($OSDSearchDrive.Root)$CallScript"

            Write-Verbose "Found PowerShell Script: $FoundCallScript"
            if (Test-Path $FoundCallScript) {$OSDCallScripts += Get-Item $FoundCallScript | Select-Object -Property FullName}
        }

        #Call found scripts
        foreach ($OSDCallScript in $OSDCallScripts) {
            Write-Verbose "Call: $($OSDCallScript.FullName)"
            & "$($OSDCallScript.FullName)" -ErrorAction SilentlyContinue
        }
    }
    #======================================================================================================
    #    AddModules
    #======================================================================================================
    if ($AddModules.IsPresent) {
        $OSDSearchDrives = Get-PSDrive -PSProvider 'FileSystem'
        foreach ($OSDSearchDrive in $OSDSearchDrives) {
            $OSDSearchPath = "$($OSDSearchDrive.Root)Modules"
            if (Test-Path "$OSDSearchPath") {
                Write-Verbose "Module Search Path: $OSDSearchPath"
                Get-ChildItem "$OSDSearchPath" | `
                Where-Object {$_.PSIsContainer} | `
                ForEach-Object {
                    Write-Verbose "Add Module: $($_.FullName)"
                    Copy-Item -Path "$($_.FullName)" -Destination "$PSHome\Modules" -Recurse -Force -ErrorAction SilentlyContinue
                }
            }
        }
    }
    #======================================================================================================
    #    ImportModule
    #======================================================================================================
    foreach ($item in $ImportModule) {
        try {Import-Module -Name "$Item" -Force}
        catch {Write-Warning "Unable to Import Module $Item"}
    }
    #======================================================================================================
    #    wpeutil
    #======================================================================================================
    if ($InitializeNetwork.IsPresent) {
        Write-Verbose 'OSDWinPE: wpeutil InitializeNetwork'
        Start-Process -WindowStyle Hidden -FilePath wpeutil -ArgumentList 'InitializeNetwork' -Wait
        Start-Sleep -Seconds 10
    }
    if ($InitializeNetworkNoWait.IsPresent) {
        Write-Verbose 'OSDWinPE: wpeutil InitializeNetwork /NoWait'
        Start-Process -WindowStyle Hidden -FilePath wpeutil -ArgumentList ('InitializeNetwork','/NoWait')
    }
    if ($WaitForNetwork.IsPresent) {
        Write-Verbose 'OSDWinPE: wpeutil WaitForNetwork'
        Start-Process -WindowStyle Hidden -FilePath wpeutil -ArgumentList 'WaitForNetwork' -Wait
    }
    if ($WaitForRemovableStorage.IsPresent) {
        Write-Verbose 'OSDWinPE: wpeutil WaitForRemovableStorage'
        Start-Process -WindowStyle Hidden -FilePath wpeutil -ArgumentList 'WaitForRemovableStorage' -Wait
    }
    if ($DisableFirewall.IsPresent) {
        Write-Verbose 'OSDWinPE: wpeutil DisableFirewall'
        Start-Process -WindowStyle Hidden -FilePath wpeutil -ArgumentList 'DisableFirewall' -Wait
    }
    if ($UpdateBootInfo.IsPresent) {
        Write-Verbose 'OSDWinPE: wpeutil UpdateBootInfo'
        Start-Process -WindowStyle Hidden -FilePath wpeutil -ArgumentList 'UpdateBootInfo'
    }
    #======================================================================================================
    #    Microsoft DaRT
    #======================================================================================================
    if (($RemoteRecovery.IsPresent) -and (Test-Path "$env:windir\System32\RemoteRecovery.exe")) {
        Write-Verbose 'OSDWinPE: Microsoft DaRT Remote Recovery'
        Start-Process -WindowStyle Minimized -FilePath RemoteRecovery.exe -ArgumentList '-nomessage'
    }
    #======================================================================================================
    #    Reboot Shutdown
    #======================================================================================================
    if ($Reboot.IsPresent) {
        Write-Verbose 'OSDWinPE: wpeutil Reboot'
        Start-Process -WindowStyle Hidden -FilePath wpeutil -ArgumentList 'Reboot'
    }
    if ($Shutdown.IsPresent) {
        Write-Verbose 'OSDWinPE: wpeutil Shutdown'
        Start-Process -WindowStyle Hidden -FilePath wpeutil -ArgumentList 'Shutdown'
    }
}