376 lines
30 KiB
PowerShell
376 lines
30 KiB
PowerShell
#//—————————————————————————-
|
||
#// 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
|
||
} |