Files

376 lines
30 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#//—————————————————————————-
#// This script by Diagg/OSDC.
#// http://osd-couture.com/
#//
#// Version : 2.4
#// Release Date : 13/06/2014
#// Latest Update : 25/07/2014
#// Usage :
#// Warning :
#// History :
#// - v1.0 : Initial release
#// - v2.0 : Added Local WDS support
#// - v2.1 : Fixed an issue with Network share !
#// - v2.2 : Changed sharing method to stay compatible with posh 2
#// - V2.3 : CustomSetting.ini variables renamed
#// - V2.4 : Fixed an issue when a network card is set to public
#// : Fixed an issue with Get-Psdrive
#// : Added more controls and error handling
#//
#//—————————————————————————
# Test values for debug
#Set-Item env:DEPLOYROOT -Value "C:\DeploymentShare"
#Set-Item env:STAGE -Value "ISO"
#Set-Item env:PLATFORM -Value "x86"
#Set-Item env:CONTENT -Value "C:\DeploymentShare\Boot\LiteTouchPE_x86.wim"
#region Usefull Functions
Function Write-Log
{
Param([string]$Mess,[Bool]$WriteToLog,[Bool]$WriteToHost)
# $Mess = Message to be Written on the log file
# $WriteToLog = If true the Write to logfile
# $WriteToHost =If true the Write to Console
If ( $WriteToLog -eq $true)
{
$Date =Get-Date
Write-output $("$Date - $Mess")|Out-File -width 500 -FilePath $logFile -Append
#Write-Verbose $("$Date - $Mess")
}
If ( $WriteToHost -eq $true)
{
Write-host $("$Date - $Mess")
}
}
Function Exit-Script
{
#Clean up
Write-log -Mess "---------------------------------------------------" -WriteToLog 1 -WriteToHost 1
Write-log -Mess "#### Clean-up ####" -WriteToLog 1 -WriteToHost 1
Write-log -Mess "---------------------------------------------------" -WriteToLog 1 -WriteToHost 1
If (-not $WDS_Local)
{
If ($CopyOnWDS)
{
Write-log -Mess ("Removing file from remote WDS : " + $WDS_LocalDrive + ":\LiteTouchPE_" + $Platform +".wim") -WriteToLog 1 -WriteToHost 1
Remove-Item ($WDS_LocalDrive + ":\LiteTouchPE_" + $Platform +".wim") -verbose
If (!(Test-Path($WDS_LocalDrive + ":\LiteTouchPE_" + $Platform +".wim")))
{
Write-log -Mess ( $WDS_LocalDrive + ":\LiteTouchPE_" + $Platform +".wim, removed successfully !!") -WriteToLog 1 -WriteToHost 1
}
Else
{
Write-log -Mess ("Error, Unable to remove " + $WDS_LocalDrive + ":\LiteTouchPE_" + $Platform +".wim") -WriteToLog 1 -WriteToHost 1
}
}
# Remove Mapped Drive
If ($Drv)
{
Write-log -Mess ("Removing mapped Drive " + $Drv) -WriteToLog 1 -WriteToHost 1
$Net.RemoveNetworkDrive($Drv)
}
# Close the Remote Connection
Write-log -Mess ("Removing Ps Session " + $RemoteSession) -WriteToLog 1 -WriteToHost 1
Remove-PSSession -Session $RemoteSession -verbose
If ($RemoteSession.State -eq "Closed")
{
Write-log -Mess "Session closed Successfully !!! " -WriteToLog 1 -WriteToHost 1
}
Else
{
Write-log -Mess "Error Closing session" -WriteToLog 1 -WriteToHost 1
}
}
Write-log -Mess "---------------------------------------------------" -WriteToLog 1 -WriteToHost 1
Write-log -Mess "# #" -WriteToLog 1 -WriteToHost 1
Write-log -Mess "---------------------------------------------------" -WriteToLog 1 -WriteToHost 1
Exit
}
#EndRegion
Cls
# Log file path
$logFile = "c:\Windows\logs\WDS-BootImageUpdate.log"
# "Update Deployment Share" current phase
$DeployRoot = (Get-ChildItem env:DEPLOYROOT).value
$Platform = (Get-ChildItem env:PLATFORM).value
$Content = (Get-ChildItem env:CONTENT).value
$Stage = (Get-ChildItem env:STAGE).value
#Clean Up log File
If ((Test-Path -LiteralPath $($logFile)) -and ($Stage -eq "WIM") -and ($Platform -eq "x86"))
{
Remove-Item $logFile
}
#Start-Transcript -path $logFile -Append
Write-log -Mess "---------------------------------------------------" -WriteToLog 1 -WriteToHost 1
Write-log -Mess "#### Updating $Platform ####" -WriteToLog 1 -WriteToHost 1
Write-log -Mess "---------------------------------------------------" -WriteToLog 1 -WriteToHost 1
Write-log -Mess "Starting WDS Update" -WriteToLog 1 -WriteToHost 1
Write-log -Mess ("DEPLOYROOT: " + $DeployRoot) -WriteToLog 1 -WriteToHost 1
Write-log -Mess ("PLATFORM: " + $Platform) -WriteToLog 1 -WriteToHost 1
Write-log -Mess ("CONTENT: " + $Content) -WriteToLog 1 -WriteToHost 1
Write-log -Mess ("STAGE: " + $Stage) -WriteToLog 1 -WriteToHost 1
If ($Stage -eq "ISO")
{
# Initialisation
$Customsettings = ($DeployRoot+"\Control\CustomSettings.ini")
$TempContent = ($Content + "\Sources\Boot.wim")
# Following line is for debug puropse only, don't forget to comment back when using in MDT.
#$TempContent = $Content
# WDSServerURI
$WDS = (Select-String -path $Customsettings -Pattern WDS-Update|ForEach {$_.Line -replace "WDS-Update=",""})
If ($WDS -like "\\*\*")
{
#Path is UNC
$WDS_Path = $WDS
$WDS_RemoteFolder = $WDS_path.Split("\")[($WDS_path.Split("\").Length)-1]
$WDS = $WDS.split("\")[2]
$WDS_Local = $false
Write-log -Mess ("WDS is remote with path: " + $WDS_Path) -WriteToLog 1 -WriteToHost 1
}
ElseIf ($WDS -like "*:\*")
{
#Path is Local
$WDS_Path = $WDS
$WDS_Local = $true
Write-log -Mess ("WDS is local with path: " + $WDS_Path) -WriteToLog 1 -WriteToHost 1
}
ElseIf ($WDS -like "*\*")
{
#Path is UNC but "\\" are missing
$WDS_Path = "\\"+$WDS
$WDS_RemoteFolder = $WDS_path.Split("\")[($WDS_path.Split("\").Length)-1]
$WDS = $WDS.split("\")[0]
$WDS_Local = $false
Write-log -Mess ("WDS is remote with path: " + $WDS_Path) -WriteToLog 1 -WriteToHost 1
}
Else
{
#Path is not valid !!!
Write-log -Mess "Unable to locate WDS path in Customsettings.ini, Aborting !" -WriteToLog 1 -WriteToHost 1
Exit-Script
}
# Login to WDS Server if not local
If (-not $WDS_Local)
{
$user = (Select-String -path $Customsettings -Pattern WDS-User|ForEach {$_.Line -replace "WDS-User=",""})
# Password to WDS Server
$Pword = (Select-String -path $Customsettings -Pattern WDS-Password|ForEach {$_.Line -replace "WDS-Password=",""})
$Pword = [System.Text.Encoding]::UNICODE.GetString([System.Convert]::FromBase64String($Pword))
$Pword2 = $Pword
$Pword = ConvertTo-SecureString -String $Pword -AsPlainText -Force
# Cypher credential
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user, $Pword
}
# Image Name to update/create
$WDS_Image = ((Select-String -path $Customsettings -Pattern WDS-Image|ForEach {$_.Line -replace "WDS-Image=",""}) + "-" + $Platform )
If (!$WDS_Image)
{
#Image Name is not valid !!!
Write-log -Mess "WDS Image name not specified or invalid, Aborting !" -WriteToLog 1 -WriteToHost 1
Exit-Script
}
# Check for local PS Remoting
If ((Get-Service WinRm).Status -ne "Running")
{
try
{
Enable-PSRemoting force -verbose
}
catch
{
If ($_.Exception.ToString() -like '*this machine is set to Public*')
{
Get-NetConnectionProfile -NetworkCategory public|Set-NetConnectionProfile -NetworkCategory Private
Enable-PSRemoting force -verbose
}
}
}
# Check if any remote computer can be member of the trusted list
If (-not $WDS_Local)
{
If ( -not (Get-ChildItem wsman:localhost\client\TrustedHosts).value -like "*")
{
Set-WSManInstance -ResourceURI winrm/config/client -ValueSet @{TrustedHosts = "*"}
}
}
#Establishing a persistent remote session
If(!$WDS_Local)
{
$RemoteSession = New-PSSession -ComputerName $WDS -Credential $Credential -Verbose
$toto = $RemoteSession.state
# Map Network drive to copy the new image
If ((Get-PSDrive).Displayroot -like $WDS_Path -or (Get-PSDrive).root -like $WDS_Path )
{
$WDS_LocalDrive = Get-PSDrive|where{$_.Displayroot -eq $WDS_Path -or $_.Root -eq $WDS_Path}
$WDS_LocalDrive = ($WDS_LocalDrive).Name
}
Else
{
# Using an alternative method to stay comaptible with powershell 2
If ((host).version.Major -gt 3)
{
#choose a random drive letter (By Shay Lavy)
$Drv = ls function:[d-z]: -n|?{!(test-path $_)}|random
$net = new-object -ComObject WScript.Network
$net.MapNetworkDrive($Drv, $WDS_Path, $false, $user, $Pword2)
$WDS_LocalDrive = ($net.EnumNetworkDrives()|where {$_ -like $Drv}).trim(":")
if (!$WDS_LocalDrive -eq $Drv)
{
Write-log -Mess ("Unable to map Network Drive, Aborting..." ) -WriteToLog 1 -WriteToHost 1
Exit-Script
}
}
Else
{
$WDS_LocalDrive = New-PSDrive -Name "WDS001" -PSProvider FileSystem -Root $WDS_Path -Credential $Credential -verbose
$WDS_LocalDrive = ($WDS_LocalDrive).Name
If (!$WDS_LocalDrive)
{
Write-log -Mess ("Unable to map Network Drive, Aborting..." ) -WriteToLog 1 -WriteToHost 1
Exit-Script
}
}
}
Write-log -Mess ("Remote WDS mapped with Letter : " + $WDS_LocalDrive) -WriteToLog 1 -WriteToHost 1
#Copy File to The WDS
Write-log -Mess ("Copying file " + $TempContent + " to " +$WDS_LocalDrive + ":\LiteTouchPE_" + $Platform +".wim") -WriteToLog 1 -WriteToHost 1
Copy-Item $TempContent -Destination ($WDS_LocalDrive + ":\LiteTouchPE_" + $Platform +".wim") -verbose
If (Test-Path($WDS_LocalDrive + ":\LiteTouchPE_" + $Platform +".wim"))
{
Write-log -Mess ("File " + $WDS_LocalDrive + ":\LiteTouchPE_" + $Platform +".wim, copied successfully !!!") -WriteToLog 1 -WriteToHost 1
$CopyOnWDS = $true
}
Else
{
Write-log -Mess ("Error, unable to copy " + $WDS_LocalDrive + ":\LiteTouchPE_" + $Platform +".wim, aborting !!!") -WriteToLog 1 -WriteToHost 1
}
}
# Check if the boot image already exist on the remote WDS
If(!$WDS_Local)
{
$Iretval = Invoke-Command -Session $RemoteSession -ArgumentList $WDS_RemoteFolder -ScriptBlock `
{
Param($WDS_RemoteFolder)
$BootImages = (Get-WdsBootImage).name
# Set a variable remotely with the WDS folder path
$WDS_RemotePath = ((gwmi -class win32_share)|where { $_.Name -like $WDS_RemoteFolder}).path
$BootImages
}
Write-log -Mess ("list of Remote images found : " + $Iretval ) -WriteToLog 1 -WriteToHost 1
}
Else
{
$Iretval = (Get-WdsBootImage).name
}
# If Image already exists, Update the image (Remove it)
If ($Iretval -like $WDS_Image)
{
Write-log -Mess ("The image " + $WDS_Image + " was found on the remote WDS and will be updated" ) -WriteToLog 1 -WriteToHost 1
# Remove the Old Image
If (!$WDS_Local)
{
$Iretval = Invoke-Command -Session $RemoteSession -ArgumentList $WDS_Image, $Platform -ScriptBlock `
{
Param($WDS_Image, $Platform)
Remove-WdsBootImage -imageName $WDS_Image -architecture $Platform -verbose
$BootImages = (Get-WdsBootImage).name
$BootImages
}
}
Else
{
Remove-WdsBootImage -imageName $WDS_Image -architecture $Platform -verbose
$Iretval = (Get-WdsBootImage).name
}
# verify if the image was correctly removed
If ($Iretval -like $WDS_Image)
{
Write-log -Mess ("Unable to remove old Image" + $WDS_Image + "...Exit Program !!!") -WriteToLog 1 -WriteToHost 1
Exit-Script
}
Else
{
Write-log -Mess ("Old Image " + $WDS_Image + " was removed Successfully !") -WriteToLog 1 -WriteToHost 1
}
}
# Import the new image
$Date = Get-Date
If (!$WDS_Local)
{
$Iretval = Invoke-Command -Session $RemoteSession -ArgumentList $WDS_Image, $Platform, $Date -ScriptBlock `
{
Param($WDS_Image, $Platform, $Date)
Import-WdsBootImage -Path ($WDS_RemotePath + "\LiteTouchPE_" + $Platform + ".wim") -NewImageName $WDS_Image -NewDescription ("Updated By MDT: " + $Date) SkipVerify -verbose
$BootImages = (Get-WdsBootImage).name
$BootImages
}
}
Else
{
Import-WdsBootImage -Path ($TempContent) -NewImageName $WDS_Image -NewDescription ("Updated By MDT: " + $Date) SkipVerify -verbose
$Iretval = (Get-WdsBootImage).name
}
# Verify if the new image was correctly uploaded
If ($Iretval -like $WDS_Image)
{
Write-log -Mess ("Image " + $WDS_Image + " uploaded Successfully on the remote WDS!") -WriteToLog 1 -WriteToHost 1
Write-log -Mess ("Image updated with the following comment => Updated By MDT: " + $Date) -WriteToLog 1 -WriteToHost 1
Write-log -Mess ("List of remote Images : " + $Iretval) -WriteToLog 1 -WriteToHost 1
}
Else
{
Write-log -Mess ("Unable to upload new Image" + $WDS_Image + "...Exit Program !!!") -WriteToLog 1 -WriteToHost 1
Exit-Script
}
Exit-Script
}
Else
{
Write-log -Mess "Awaiting next stage to proceed" -WriteToLog 1 -WriteToHost 1
}