Waiting for an IP Address

I received at work a Surface Pro 2 and Windows To Go certified USB sticks. Because of the UEFI requirements and the fact that Surface devices don’t have a built-in ethernet adapter, I changed my mind about how to industrialise the installation of such devices.

As my administrative distribution point is portable and I decided to move it to the USB stick and perform the installation directly from the USB stick without any network.

On the USB distribution point, I’ve got the extracted ISO of Windows 8.1 (Enterprise edition in my case), a custom answer file,… and drivers:

As long with these drivers there are some interesting PDF files to download and at the end of document, one can read:

Good idea 🙂
I wanted to keep it simple and started writing a post-installation script exclusively in PowerShell that first deploys drivers.
Here’s how my post-installation script starts:

#region drivers
$letter = (Get-Disk | ? BusType -eq "USB" | Get-Partition)[0].DriveLetter
Write-Verbose -Message "Starting to install drivers" -Verbose
(Get-ChildItem -Path "$($letter):\DISTRIB\WIN81\DRIVERS_x64" -Directory | 
     Sort LastwriteTime -Descending:$false | 
     select -Last 1
).FullName | ForEach-Object {
     Get-ChildItem -Path $_ -Recurse -Filter *.inf  -Exclude autorun.inf | 
     ForEach-Object -Process {
        '{0}' -f $_.FullName
        & (Get-Command "$($env:SystemRoot)\system32\pnputil.exe") @('/i','/a',"$($_.FullName)")
    }
}
#endregion drivers

After loading the wireless driver, I could start configuring the wireless interface and once on the network I’ll perform the remaining tasks that require network availability: activation, updating,…

Getting on the network is a crucial task. If it fails, all the remaining tasks would also fail.

I wanted to have also an elegant way of detecting when my wireless interface was fully configured and ready to perform online tasks.

I couldn’t use the following old trick as it isn’t robust and it is sequential.

Test-Connection -ComputerName ::1 -Count 10

I chose the .Net eventing path. Here’s how:

#region wireless

$network = New-Object System.Net.NetworkInformation.NetworkChange

Register-ObjectEvent -InputObject $network -EventName NetworkAvailabilityChanged -Action {
    (New-Event -SourceIdentifier "NetworkAvailabilityChanged" -Sender $args[0] –EventArguments $args[1].SourceEventArgs.NewEvent.TargetInstance)
}

# Perform some certificate related tasks
<# ... #>
# Start some services
Get-Service -Name dot3svc | Set-Service -StartupType Automatic
Get-Service -Name eaphost,ndisuio | Start-Service -ErrorAction SilentlyContinue
Start-Service -Name dot3svc
# Import the wireless profile
& (Get-Command "$($env:SystemRoot)\system32\netsh.exe") @("wlan","add","profile","filename=$($letter):\Wi-Fi-Intranet.xml","interface=Wi-Fi","user=all")

Wait-Event -SourceIdentifier NetworkAvailabilityChanged
Get-Event -SourceIdentifier NetworkAvailabilityChanged | Remove-Event

#endregion wireless

Bonus: the .Net Class [System.Net.NetworkInformation.NetworkChange] handles two kind of events:

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s