<?xml version="1.0"?>
<rss version="2.0"><channel><title/><link>https://www.edugeek.net/blogs/blog/1710-dj-1701s-blog/</link><description/><language>en</language><item><title>OLD - Shortcut deployment script</title><link>https://www.edugeek.net/blogs/entry/1141-old-shortcut-deployment-script/</link><description><![CDATA[<p>The following is the latest powershell shortcut deployment script, first shown in <a href="https://www.edugeek.net/forums/windows-server-2000-2003/76664-cc3-vanilla-windows-without-wiping-4.html#post1404554" rel="">http://www.edugeek.net/forums/windows-server-2000-2003/76664-cc3-vanilla-windows-without-wiping-4.html#post1404554</a></p><p> </p><p>
Updates include comment clarification, hiding errors when dealing with files with no shortcut path/MSI generated shortcuts.</p><p> </p><p>
Latest script can be found here: <a href="https://github.com/DJ-1701/ShortcutDeploy" rel="external nofollow">https://github.com/DJ-1701/ShortcutDeploy</a></p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p>
</p><pre class="ipsCode">
# Specify source and destination of shortcut folders below.
# ****************************************************************************
# * Note: In the source location, create two folders named 32-Bit and 64-Bit *
# *       to host your Start Menu shortcuts (as shortcut paths may vary).    *
# ****************************************************************************
$Source = "\\ABC-SVR-01\Applications$\StartMenu"
$Destination="C:\ProgramData\FolderName\Windows\Start Menu"

# Inform user if no Source or Destination has been provided.
If (($Source -eq "") -or ($Destination -eq ""))
{
   Write-Host "Missing Source and/or Destination, please check and try again."
   Exit
}

# If there is a trailing backslash for $Source and/or $Destination, remove the backslash.
If ($Source.Substring($Source.Length-1) -eq "\")
{
   $Source = $Source.Substring(0,$Source.Length-1)
}
If ($Destination.Substring($Destination.Length-1) -eq "\")
{
   $Destination = $Destination.Substring(0,$Destination.Length-1)
}

# Update the Source path to include the OS Architecture type to the end of the path.
# If no OS Architecture is returned, then use the 32-Bit shortcut folder.
$Bit = ((Get-WMIObject Win32_OperatingSystem).OSArchitecture)
If ($Bit -eq "") {$Bit = "32-Bit"}
$Source = $Source + "\" + $Bit

# Inform user if Source does not exist.
If (!(Test-Path($Source)))
{
   Write-Host "The Source location does not exist, please check and try again."
   Exit
}

# Get the latest last modified date on all shortcuts in Source and Destination paths.
$NetworkStamp = Get-ChildItem "$Source\*" -Recurse -Force -include @("*.lnk","*.xml","*.appref-ms")`
               | Where {!$_.PsIsContainer} | select Name,DirctoryName, LastWriteTime `
               | Sort LastWriteTime -descending | select -first 1
$LocalStamp = Get-ChildItem "$Destination\*" -Recurse -Force -include @("*.lnk","*.xml","*.appref-ms") -ErrorAction SilentlyContinue `
             | Where {!$_.PsIsContainer} | select Name,DirctoryName, LastWriteTime `
             | Sort LastWriteTime -descending | select -first 1

# If there are any differences in the last modified date:
# 1) Delete files in Destination (if it exists).
# 2) Copy files from Source to Destination.
If ($NetworkStamp.LastWriteTime -ne $LocalStamp.LastWriteTime)
{
   If (Test-Path($Destination))
   {
       Remove-Item "$Destination" -Recurse -Force
   }
   New-Item -ItemType directory -Path "$Destination"
   Copy-Item "$Source\*" -Destination "$Destination" -Recurse
}

# Create a list of folders copied to the destination folder.
$ListOfFolders = Get-ChildItem $Destination -Recurse -Force | Where-Object {$_.PSIsContainer} `
                | Sort-Object FullName -Descending | % { $_.FullName }

# Create a shell object, so we can check if the shortcuts are valid.
$sh = New-Object -COM WScript.Shell

# Check if Array is Null (Prevents ForEach null bug in PowerShell 2).
If ($ListOfFolders -ne $null)
{
   
   # Do the following for every folder we scanned.
   FOREACH ($Folder in $ListOfFolders)
   {
       
       # Set the hidden flag to True for the folder.
       # Note: This will hide the folder later on if applications do not exist.
       $AllItemsHidden = $true
       
       # Get a list of all shortcuts in the current folder.
       $ListOfShortcuts = Get-ChildItem "$Folder\*" -Force -include *.lnk `
                          | % { $_.FullName }
       
       # Check if Array is Null (Prevents ForEach null bug in PowerShell 2).
       If ($ListOfShortcuts -ne $null)
       {
           
           # Do the following for every shortcut we scanned.
           FOREACH ($Shortcut in $ListOfShortcuts)
           {
               
               # Find out if the shortcut is hidden.
               $Item = Get-Item $Shortcut -Force
               $CheckHidden = (Get-ItemProperty $Item).Attributes.ToString() -match "Hidden"
               
               # Get the target path of the shortcut (the path of the application).
               # If it refers to C drive (C:), check if it exists, and ensure the shortcut
               # is visible to the users, otherwise hide the shortcut.
               $PathOfApplication = $sh.CreateShortcut($Shortcut).TargetPath
               If ($PathOfApplication.Length -ge 2)
               {
                   If ($PathOfApplication.Substring(0,2) -eq "C:")
                   {
                       If (Test-Path($PathOfApplication))
                       {
                           $AllItemsHidden = $false
                           If ($CheckHidden)
                           {
                               $Item.Attributes = $Item.Attributes -bxor [system.IO.FileAttributes]::Hidden
                           }
                       }
                       ElseIf ((!(Test-Path($PathOfApplication))) -and (!($CheckHidden)))
                       {
                           $Item.Attributes = $Item.Attributes -bxor [system.IO.FileAttributes]::Hidden
                       }
                   }
               }
               If (($Item.Directory.Name -eq "Programs") -or ($Item.DirectoryName.ToLower().Contains("\Programs\".ToLower())))
               {
                       $CheckHidden = (Get-ItemProperty $Item).Attributes.ToString() -match "Hidden"
                       If (!($CheckHidden))
                       {
                           $Item.Attributes = $Item.Attributes -bxor [system.IO.FileAttributes]::Hidden
                       }
               }
           }
   
           # List all files in the folder (excluding desktop.ini and thumbs.db, which aren't required).
           $ListOfSubFilesAndFolders = Get-ChildItem "$Folder\*" -Force -exclude "desktop.ini","thumbs.db" `
                                       | % { $_.FullName }
           
           # Check if Array is Null (Prevents ForEach null bug in PowerShell 2).
           If ($ListOfSubFilesAndFolders -ne $null)
           {
               
               # Do the following for every file or subfolder we scanned.
               FOREACH ($SubFilesOrFolder in $ListOfSubFilesAndFolders)
               {
                   
                   # Find out if the file is hidden. If it is not, then it is a required resource.
                   # inform the program not to hide the folder.
                   $Item = Get-Item $SubFilesOrFolder -Force
                   $CheckHidden = $Item.Attributes.ToString() -match "Hidden"
                   If ($CheckHidden -eq $false)
                   {
                       $AllItemsHidden = $false
                   }
               }
           }

           # If all of the files are hidden in the folder, then hide the unrequired folder.
           # If any file is unhidden in the folder, then unhide the required folder.
           $Item = Get-Item $Folder -Force
           $CheckHidden = (Get-ItemProperty $Item).Attributes.ToString() -match "Hidden"
           If (($AllItemsHidden -and !($CheckHidden)) -or (!($AllItemsHidden) -and $CheckHidden))
           {
               $Item.Attributes = $Item.Attributes -bxor [system.IO.FileAttributes]::Hidden
           }
       }

       If (($Item.Directory.Name -ne $null) -or ($Item.DirectoryName -ne $null))
       {
           If (($Item.Directory.Name -eq "Programs") -or ($Item.DirectoryName.ToLower().Contains("\Programs\".ToLower())))
           {
                   $CheckHidden = (Get-ItemProperty $Item).Attributes.ToString() -match "Hidden"
                   If (!($CheckHidden))
                   {
                       $Item.Attributes = $Item.Attributes -bxor [system.IO.FileAttributes]::Hidden
                   }
           }
       }
   }
}
</pre><div></div><p></p>]]></description><guid isPermaLink="false">1141</guid><pubDate>Mon, 04 Feb 2019 12:25:49 +0000</pubDate></item><item><title>OLD - Boot and Logon wallpaper generation using PowerShell.</title><link>https://www.edugeek.net/blogs/entry/1133-old-boot-and-logon-wallpaper-generation-using-powershell/</link><description><![CDATA[<p>Latest version of scripts and information can be found on: <a href="https://github.com/DJ-1701/GenerateWallpaper" rel="external nofollow">https://github.com/DJ-1701/GenerateWallpaper</a></p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p>
Old information below...</p><p> </p><p>
</p><p><span style="font-size:8px;">
The following details shows you how to create Boot and Logon wallpapers using existing wallpaper and adding an overlay of text which can display your school name, computer name, etc via PowerShell scripts which I have created and you may reuse, edit, butcher, etc. </span><img alt=":)" data-src="https://www.edugeek.net/uploads/emoticons/smile.png.e38e01f2a4850c4158c039aea82ac2a8.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /><span style="font-size:8px;">.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Examples of this style can be found below:</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Boot</span></p><p><span style="font-size:8px;">
</span><a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2018_11/backgroundDefault.jpg.7837a968b2d51b95e1cdbe3563088925.jpg" data-fileid="375" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="backgroundDefault.thumb.jpg.7be3db1e8eb30371003a462c0212b186.jpg" data-fileid="375" data-src="https://www.edugeek.net/uploads/monthly_2025_03/backgroundDefault.thumb.jpg.7be3db1e8eb30371003a462c0212b186.jpg" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Logon</span></p><p><span style="font-size:8px;">
</span><a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2018_11/LogonInfo.jpg.44913cf78c14094bd0e74a4182b45925.jpg" data-fileid="376" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="LogonInfo.thumb.jpg.225bee33e1373888afe2508577847514.jpg" data-fileid="376" data-src="https://www.edugeek.net/uploads/monthly_2025_03/LogonInfo.thumb.jpg.225bee33e1373888afe2508577847514.jpg" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
For this exercise we are going to use some pre-created wallpapers for Windows 10 in 19x6 (aka Widescreen) and 4x3 (aka Standard) resolutions, which can be </span><a href="https://drive.google.com/open?id=1Sr4ZWIJtStYvWMOky2gFNi6r78Lp3wY4" rel="external nofollow"><span style="font-size:8px;">downloaded here.</span></a></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Extract the zip file to a folder with the School’s name. So, the folder path to both directories should be:</span></p><p><span style="font-size:8px;">
SchoolName\Wallpaper\4x3</span></p><p><span style="font-size:8px;">
SchoolName\Wallpaper\19x6</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Feel free to have a look at the images in the folder, and delete and add images as you see fit. There are around 280MB worth of images, so you may want to delete some if your machines don’t have much space. After you have finished, copy the SchoolName directory to your Domain Controller’s netlogon share (i.e. </span><span style="font-size:8px;"><strong>\\FQDN\netlogon</strong></span><span style="font-size:8px;"> - where FQDN is the fully qualified domain name for your active directory domain).</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Next we are going to take a look at the basic code.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
</span><span style="font-size:8px;"><strong>Update Wallpaper</strong></span></p><p><span style="font-size:8px;">
</span></p><pre class="ipsCode">
# Wallpaper folder source.
$Domain = (Get-WmiObject -Class Win32_ComputerSystem).Domain
$NetworkSource = "\\$Domain\NetLogon\SchoolName\Wallpaper"
$LocalSource = "$Env:ProgramFiles\SchoolName\Wallpaper"

# Custom wallpaper override file.
# Note: Value used to prevent deletion of local file when mirroring.
$Override = "$LocalSource\Override.jpg"

# Path to robocopy command.
$WinDir = (Get-Childitem env:WinDir).Value
$Robocopy = "$WinDir\System32\Robocopy.exe"
If (!(Test-Path($Robocopy)))
{
   Write-Host "$Robocopy does not exist."
   Exit
}

If (!(Test-Path($NetworkSource)))
{
   Write-Host "$NetworkSource does not exist."
   Exit
}

If (!(Test-Path($LocalSource)))
{
     New-Item -ItemType directory -Path $LocalSource
}

# Update local wallpapers.
&amp;$Robocopy "$NetworkSource" "$LocalSource" /MIR /XF "$Override" /R:1 /W:1 /NP
</pre><div></div><p></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Copy and paste the code above into PowerShell ISE, so you can create a PS1 file, and test the code if you so wish.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Please note:</span></p><p>
</p><ul><li><span style="font-size:8px;">PowerShell ISE needs to be run as an Administrator for certain aspects of the script to work.</span><br />
</li><li><span style="font-size:8px;">Rename SchoolName in the script to the actual School Name (i.e. the folder you just copied to you Domain Controller’s netlogon share).</span><br />
</li></ul><p></p><p>
<span style="font-size:8px;">Save the script as \\FQDN\netlogon\Update Wallpaper.ps1 (where FQDN is the fully qualified domain name for your active directory domain).</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
When running the script as an Administrator, you should find this will copy the SchoolName folder down from the netlogon share to the C:\Program Files folder on the local computer.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
</span><span style="font-size:8px;"><strong>Boot Info</strong></span></p><p><span style="font-size:8px;">
</span></p><pre class="ipsCode">
# Text for the wallpaper.
$TextLabel = "School Address Here`r`nTelephone: Telephone Number Here`r`nComputer Name: "+((Get-Childitem env:ComputerName).Value)
$TextSizePoint = 18

# Text box colour.
$BoxRed = 22
$BoxGreen = 176
$BoxBlue = 221

# Text colour.
$TextRed = 255
$TextGreen = 255
$TextBlue = 255

# Wallpaper source folder.
$LocalSource = "$Env:ProgramFiles\SchoolName\Wallpaper"

# Custom wallpaper override file.
$Override = "$LocalSource\Override.jpg"

# Completed wallpaper destination location.
$WinDir = (Get-Childitem env:WinDir).Value
$SystemBackgroundDir = "$WinDir\system32\oobe\info\backgrounds"
$DestinationFile = "$SystemBackgroundDir\backgroundDefault.jpg"

If (!(Test-Path($LocalSource)))
{
   Write-Host "$LocalSource does not exist."
   Exit
}

If (!(Test-Path("$SystemBackgroundDir")))
{
  New-Item -ItemType directory -Path "$SystemBackgroundDir"
}

# Find current screen resolution.
# Note: Interrogating [system.Windows.Forms.Screen] at boot returns false 1024x768.
#       Therefore, a separate login script stores this data on user login to a registry key.
#       After which the PC can check this key. If data does not exist, it will use
#       recommended supported resolution data. If this fails, it will default to 1024x768.
$RegistryPath = "HKLM:\Software\MachineData"
If ((Test-Path $RegistryPath))
{
   If (((Get-ItemProperty -Path $RegistryPath).Horizontal -ne $null) -and ((Get-ItemProperty -Path $RegistryPath).Vertical -ne $null))
   {
       $Horizontal = [int]((Get-ItemProperty -Path $RegistryPath).Horizontal)
       $Vertical = [int]((Get-ItemProperty -Path $RegistryPath).Vertical)
   }
}
If ($Horizontal -eq $null) {$Horizontal = [int]((Get-WmiObject -Class Win32_VideoController).CurrentHorizontalResolution)}
If ($Vertical -eq $null) {$Vertical = [int]((Get-WmiObject -Class Win32_VideoController).CurrentVerticalResolution)}
If ($Horizontal -eq $null) {$Horizontal = [int]"1024"}
If ($Vertical -eq $null) {$Vertical = [int]"768"}

If ($Horizontal/$Vertical -le 1.4)
{
   $Ratio = "4x3"
}
Else
{
   $Ratio = "16x9"
}
$SourceDir = "$LocalSource\$Ratio"
If (!(Test-Path($SourceDir)))
{
   Write-Host "$SourceDir does not exist."
   Exit
}

# Select a random file as the source wallpaper.
$Files = (dir -Path $SourceDir\* -Recurse).FullName
$SourceFile = $Files | Get-Random

# If override wallpaper exists, change source file.
If ((Test-Path($Override)))
{
   $SourceFile = $Override
}

# If no source file exists, exit.
If (!(Test-Path($SourceFile)))
{
   Write-Host "$SourceFile does not exist."
   Exit
}
If ($? -eq $false)
{
   Write-Host "Null Source File."
   Exit
}

# Enable the creation of images.
Add-Type -AssemblyName System.Drawing

# Select a font, size and style.
$TextSizePixels=$TextSizePoint/0.75
$Font = New-Object System.Drawing.Font("Arial",$TextSizePixels,[Drawing.FontStyle]'Bold',"Pixel")

# Get source image from source file.
$SourceImage = [system.Drawing.Image]::FromFile($SourceFile)

# Create a new bitmap at the primary monitor resolution to construct an image.
$Bitmap = New-Object System.Drawing.Bitmap($Horizontal,$Vertical)

# Create image for editing.
$Image = [system.Drawing.Graphics]::FromImage($Bitmap)

# Ensure the image is clear.
$Image.Clear([system.Drawing.Color]::FromArgb(255,255,255,255))

# Set the ARGB values required for the text and text box.
$TextARGB = [system.Drawing.Color]::FromArgb(255,$TextRed,$TextGreen,$TextBlue)
$BoxARGB = [system.Drawing.Color]::FromArgb(255,$BoxRed,$BoxGreen,$BoxBlue)

# Set area for text placement.
$Rectangle = [system.Drawing.RectangleF]::FromLTRB(0, 0, $Horizontal, $Vertical)

# Set alignment format for the font.
$FormatFont = [system.Drawing.StringFormat]::GenericDefault
$FormatFont.Alignment = [system.Drawing.StringAlignment]::Center
$FormatFont.LineAlignment = [system.Drawing.StringAlignment]::Near

# Get text path Layout to work out text box co-ordinates.
$TextPath = New-Object System.Drawing.Drawing2D.GraphicsPath
$TextPath.AddString($TextLabel,$Font.FontFamily,$Font.Style,$Font.Size,$Rectangle,$FormatFont)

# Get co-ordinates of beginning and end of text.
$StartX = $Horizontal
$StartY = $Vertical
$EndX = 0
$EndY = 0
ForEach ($PathPointRow in $TextPath.PathPoints)
{
   If ($PathPointRow.X -le $StartX){$StartX = $PathPointRow.X}
   If ($PathPointRow.Y -le $StartY){$StartY = $PathPointRow.Y}
   If ($PathPointRow.X -gt $EndX){$EndX = $PathPointRow.X}
   If ($PathPointRow.Y -gt $EndY){$EndY = $PathPointRow.Y}
}
$EndX = $EndX - $StartX
$EndY = $EndY - $StartY

# Set up the brush colours for drawing text box and text string.
$BoxBrushColour = New-Object Drawing.SolidBrush $BoxARGB
$TextBrushColour = New-Object Drawing.SolidBrush $TextARGB

# Draw image.
$Image.DrawImage($SourceImage,0,0, $Horizontal, $Vertical)

# Draw box.
$Image.FillRectangle($BoxBrushColour,$StartX,$StartY,$EndX,$EndY)

# Draw text.
$Image.DrawString($TextLabel,$Font,$TextBrushColour,$Rectangle,$FormatFont)

# Find last boot time to display on Wallpaper.
$TextLabel = "Last Boot: "+((Get-Date).DateTime)

# Select a font, size and style.
$TextSizePoint = 10
$TextSizePixels=$TextSizePoint/0.75
$Font = New-Object System.Drawing.Font("Arial",$TextSizePoint,[Drawing.FontStyle]'Bold',"Pixel")

# Set alignment format for the font.
$FormatFont = [system.Drawing.StringFormat]::GenericDefault
$FormatFont.Alignment = [system.Drawing.StringAlignment]::Near
$FormatFont.LineAlignment = [system.Drawing.StringAlignment]::Far

# Get text path Layout to work out text box co-ordinates.
$TextPath = New-Object System.Drawing.Drawing2D.GraphicsPath
$TextPath.AddString($TextLabel,$Font.FontFamily,$Font.Style,$Font.Size,$Rectangle,$FormatFont)

# Get co-ordinates of beginning and end of text, and add padding for text box.
$StartX = $Horizontal
$StartY = $Vertical
$EndX = 0
$EndY = 0
ForEach ($PathPointRow in $TextPath.PathPoints)
{
   If ($PathPointRow.X -le $StartX){$StartX = $PathPointRow.X}
   If ($PathPointRow.Y -le $StartY){$StartY = $PathPointRow.Y}
   If ($PathPointRow.X -gt $EndX){$EndX = $PathPointRow.X}
   If ($PathPointRow.Y -gt $EndY){$EndY = $PathPointRow.Y}
}
$EndX = $EndX - $StartX + 15
$EndY = $EndY - $StartY + 15
$StartY = $StartY - 5
$StartX = $StartX - 5

# Set up the brush colours for drawing text box and text string.
$BoxBrushColour = New-Object Drawing.SolidBrush $BoxARGB
$TextBrushColour = New-Object Drawing.SolidBrush $TextARGB

# Draw box.
$Image.FillRectangle($BoxBrushColour,$StartX,$StartY,$EndX,$EndY)

# Draw text.
$Image.DrawString($TextLabel,$Font,$TextBrushColour,$Rectangle,$FormatFont)

# Save edited bitmap to file.
$Bitmap.Save($DestinationFile,[system.Drawing.Imaging.ImageFormat]::Jpeg)

# Clean up and remove objects.
$SourceImage.Dispose()
$Bitmap.Dispose()
$Image.Dispose()
$SourceDestinationFile

# Open saved file.
#Invoke-Item $DestinationFile
</pre><div></div><p></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Copy and paste the code above into PowerShell ISE, so you can create a PS1 file, and test the code if you so wish.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Please note:</span></p><p>
</p><ul><li><span style="font-size:8px;">PowerShell ISE needs to be run as an Administrator for certain aspects of the script to work.</span><br />
</li><li><span style="font-size:8px;">Edit the section after '$TextLabel = "' to change the text which is saved on the wallpaper.</span><br />
</li><li><span style="font-size:8px;">Rename SchoolName in the script to the actual School Name (i.e. the folder you just copied to you Domain Controller’s netlogon share).</span><br />
</li></ul><p></p><p>
<span style="font-size:8px;">Save the script as \\FQDN\netlogon\SchoolName\Wallpaper\Boot Info.ps1 (where FQDN is the fully qualified domain name for your active directory domain).</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
When running the script as an Administrator, you should find this will grab a random file from the correct screen ratio folder (or nearest, if you have a non-standard/old widescreen) generate the text to overlay (so in this case School Address, Telephone Number and Computer Name in the top centre, and the Boot Time in the bottom left) and save the file to C:\Windows\System32\oobe\info\backgrounds\backgroundDefault.jpg.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
The reason we are using this location by default is because it is also the standard location Windows 7 looked to for a corporate wallpaper, the path can be changed on Windows 10 if you wish to place it elsewhere.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Please note that the wallpaper will not change until we update group policy to force this new file, but you can view the output in the file mentioned above.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
</span><span style="font-size:8px;"><strong>Logon Info</strong></span></p><p><span style="font-size:8px;">
</span></p><pre class="ipsCode">
# Text for the wallpaper.
$TextLabel = "School Address Here`r`n`r`nUser Name: "+($env:USERNAME)+"`r`nComputer Name: "+($env:COMPUTERNAME)+"`r`nModel: "+((Get-WmiObject Win32_ComputerSystem).Model)+"`r`nSerial Number: "+((Get-WmiObject Win32_ComputerSystemProduct).IdentifyingNumber)
$TextSizePoint = 12

# Text box colour.
$BoxRed = 0
$BoxGreen = 125
$BoxBlue = 255

# Text colour.
$TextRed = 255
$TextGreen = 255
$TextBlue = 255

# Wallpaper source folder.
$LocalSource = "$Env:ProgramFiles\SchoolName\Wallpaper"

# Completed wallpaper destination location.
$DestinationFile = "$env:temp\LogonInfo.jpg"

# Clear theme cache files.
Remove-Item -Path "$($env:APPDATA)\Microsoft\Windows\Themes\*" -Recurse -Force -ErrorAction SilentlyContinue

# Ensure image is set to Stretch to screen resolution and not tile.
Set-ItemProperty -Path 'HKCU:\Control Panel\Desktop' -Name WallpaperStyle -Value "2" -Force
Set-ItemProperty -Path 'HKCU:\Control Panel\Desktop' -Name TileWallpaper -Value "0" -Force

If (!(Test-Path($LocalSource)))
{
   Write-Host "$LocalSource does not exist."
   Exit
}

# Find current screen resolution.
# Note: Interrogating [system.Windows.Forms.Screen] at boot returns false 1024x768.
#       Therefore, this login script stores the data on user login to a registry key.
#       After which the boot script can check this key. If data does not exist, it will use
#       recommended supported resolution data. If this fails, it will default to 1024x768.
[void] [system.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$RegistryPath = "HKLM:\Software\MachineData"
$Horizontal = [int]([system.Windows.Forms.Screen]::AllScreens[0]).Bounds.Width
$Vertical = [int]([system.Windows.Forms.Screen]::AllScreens[0]).Bounds.Height
If (!(Test-Path $RegistryPath)) {New-Item -Path $RegistryPath -Force}
New-ItemProperty -Path $RegistryPath -Name "Horizontal" -Value $Horizontal -PropertyType DWORD -Force
New-ItemProperty -Path $RegistryPath -Name "Vertical" -Value $Vertical -PropertyType DWORD -Force
If ($Horizontal -eq $null) {$Horizontal = [int]((Get-WmiObject -Class Win32_VideoController).CurrentHorizontalResolution)}
If ($Vertical -eq $null) {$Vertical = [int]((Get-WmiObject -Class Win32_VideoController).CurrentVerticalResolution)}
If ($Horizontal -eq $null) {$Horizontal = [int]"1024"}
If ($Vertical -eq $null) {$Vertical = [int]"768"}

If ($Horizontal/$Vertical -le 1.4)
{
   $Ratio = "4x3"
}
Else
{
   $Ratio = "16x9"
}
$SourceDir = "$LocalSource\$Ratio"
If (!(Test-Path($SourceDir)))
{
   Write-Host "$SourceDir does not exist."
   Exit
}

# Select a random file as the source wallpaper.
$Files = (dir -Path $SourceDir\* -Recurse).FullName
$SourceFile = $Files | Get-Random

# If username does not start with Student, look to see if the user has a personal wallpaper they wish to use instead.
If (!(($env:USERNAME) -like "Student*"))
{
   If (Test-Path("$env:userprofile\Documents\Wallpaper\Wallpaper.jpg"))
   {
       $SourceFile = "$env:userprofile\Documents\Wallpaper\Wallpaper.jpg"
   }
   ElseIf (Test-Path("$env:homeshare\Wallpaper\Wallpaper.jpg"))
   {
       $SourceFile = "$env:homeshare\Wallpaper\Wallpaper.jpg"
   }
}

# If no source file exists, exit.
If (!(Test-Path($SourceFile)))
{
   Write-Host "$SourceFile does not exist."
   Exit
}
If ($? -eq $false)
{
   Write-Host "Null Source File."
   Exit
}

# Use .Net Framework to create a class to update and refresh the Wallpaper.
Add-Type @”
   using System;
   using System.Runtime.InteropServices;
   using Microsoft.Win32;

   namespace Wallpaper
   {
       public class UpdateImage
       {
           [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
       
           private static extern int SystemParametersInfo (int uAction, int uParam, string lpvParam, int fuWinIni);

           public static void Refresh(string path) 
           {
               SystemParametersInfo( 20, 0, path, 0x01 | 0x02 ); 
           }
       }
   }
“@

# Enable the creation of images.
Add-Type -AssemblyName System.Drawing

# Select a font, size and style.
$TextSizePixels=$TextSizePoint/0.75
$Font = New-Object System.Drawing.Font("Arial",$TextSizePixels,[Drawing.FontStyle]'Bold',"Pixel")

# Get source image from source file.
$SourceImage = [system.Drawing.Image]::FromFile($SourceFile)

# Create a new bitmap at the primary monitor resolution to construct an image.
$Bitmap = New-Object System.Drawing.Bitmap($Horizontal,$Vertical)

# Create image for editing.
$Image = [system.Drawing.Graphics]::FromImage($Bitmap)

# Ensure the image is clear.
$Image.Clear([system.Drawing.Color]::FromArgb(255,255,255,255))

# Set the ARGB values required for the text and text box.
$TextARGB = [system.Drawing.Color]::FromArgb(255,$TextRed,$TextGreen,$TextBlue)
$BoxARGB = [system.Drawing.Color]::FromArgb(255,$BoxRed,$BoxGreen,$BoxBlue)

# Set area for text placement.
$Rectangle = [system.Drawing.RectangleF]::FromLTRB(0, 0, $Horizontal, $Vertical)

# Set alignment format for the font.
$FormatFont = [system.Drawing.StringFormat]::GenericDefault
$FormatFont.Alignment = [system.Drawing.StringAlignment]::Far
$FormatFont.LineAlignment = [system.Drawing.StringAlignment]::Near

# Get text path Layout to work out text box co-ordinates.
$TextPath = New-Object System.Drawing.Drawing2D.GraphicsPath
$TextPath.AddString($TextLabel,$Font.FontFamily,$Font.Style,$Font.Size,$Rectangle,$FormatFont)

# Get co-ordinates of beginning and end of text, and add padding for text box.
$StartX = $Horizontal
$StartY = $Vertical
$EndX = 0
$EndY = 0
ForEach ($PathPointRow in $TextPath.PathPoints)
{
   If ($PathPointRow.X -le $StartX){$StartX = $PathPointRow.X}
   If ($PathPointRow.Y -le $StartY){$StartY = $PathPointRow.Y}
   If ($PathPointRow.X -gt $EndX){$EndX = $PathPointRow.X}
   If ($PathPointRow.Y -gt $EndY){$EndY = $PathPointRow.Y}
}
$EndX = $EndX - $StartX + 5
$EndY = $EndY - $StartY + 10
$StartY = $StartY - 5
$StartX = $StartX

# Set up the brush colours for drawing text box and text string.
$BoxBrushColour = New-Object Drawing.SolidBrush $BoxARGB
$TextBrushColour = New-Object Drawing.SolidBrush $TextARGB

# Draw image.
$Image.DrawImage($SourceImage,0,0, $Horizontal, $Vertical)

# Draw box.
$Image.FillRectangle($BoxBrushColour,$StartX,$StartY,$EndX,$EndY)

# Draw text.
$Image.DrawString($TextLabel,$Font,$TextBrushColour,$Rectangle,$FormatFont)

# Save edited bitmap to file.
$Bitmap.Save($DestinationFile,[system.Drawing.Imaging.ImageFormat]::Jpeg)

# Clean up and remove objects.
$SourceImage.Dispose()
$Bitmap.Dispose()
$Image.Dispose()
$SourceDestinationFile

# Open saved file.
#Invoke-Item $DestinationFile

# Update wallpaper.
[Wallpaper.UpdateImage]::Refresh($DestinationFile)
</pre><div></div><p></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Copy and paste the code above into PowerShell ISE, so you can create a PS1 file, and test the code if you so wish.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Please note:</span></p><p>
</p><ul><li><span style="font-size:8px;">PowerShell ISE needs to be run as an Administrator for certain aspects of the script to work.</span><br />
</li><li><span style="font-size:8px;">Edit the section after '$TextLabel ="' to change the text which is saved on the wallpaper.</span><br />
</li><li><span style="font-size:8px;">Rename SchoolName in the script to the actual School Name (i.e. the folder you just copied to you Domain Controller’s netlogon share).</span><br />
</li></ul><p></p><p>
<span style="font-size:8px;">Save the script as \\FQDN\netlogon\Logon Info.ps1 (where FQDN is the fully qualified domain name for your active directory domain).</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
When running the script as an Administrator, you should find this will grab a random file from the correct screen ratio folder (or nearest, if you have a non-standard/old widescreen) generate the text to overlay (so in this case School Address, User Name, Computer Name, Model and Serial Number in the top right) and save the file to the user’s temporary folder %Temp%\LogonInfo.jpg </span></p><pre class="ipsCode">On a typical computer this would be: C:\Users\%Username%\AppData\Local\Temp\LogonInfo.jpg[/Code]</pre><p></p><p> </p><p>
This script will also grab the most accurate data of the screens current resolution and store it in the registry location HKEY_LOCAL_MACHINE\Software\MachineData, which can then also be used by the Boot Info script.</p><p> </p><p>
Please note that the wallpaper will not change until we update group policy to force this new file, but you can view the output in the folder mentioned above.</p><p> </p><p>
[b]Group Policy</p><p> </p><p>
[/b]The group policy settings to enforce these wallpapers are as follows.</p><p> </p><p>
For the logon wallpaper, this will affect User Policy, so either create a new policy for the users, or edit an existing one and:</p><p> </p><p>
[/size]</p><p>
</p><ol style="list-style-type:decimal;"><li>[size=1]Go to User Configuration -&gt; Policies -&gt; Windows Settings -&gt; Scripts (Logon/Logoff) -&gt; Logon, and then click on the PowerShell Scripts tab, press Add, and for the script name type in the full path you stored the logon script (i.e. \\FQDN\netlogon\Logon Info.ps1).[/size]<br />
</li><li>[size=1]Go to User Configuration -&gt; Policies -&gt; Administrative Templates -&gt; Desktop -&gt; Desktop -&gt; Desktop Wallpaper, and enable the policy, specifying the location as %temp%\LogonInfo.jpg and setting the wallpaper style to Stretch.[/size]<br />
</li></ol><p></p><p>
[size=1]</p><p>
For the boot wallpaper, this will affect Computer Policy, so either create a new policy for the machines, or edit an existing one and:</p><p> </p><p>
[/size]</p><p>
</p><ol style="list-style-type:decimal;"><li>[size=1]Go to User Configuration -&gt; Policies -&gt; Windows Settings -&gt; Scripts (Logon/Logoff) -&gt; Logon, and then click on the PowerShell Scripts tab, press Add, and for the script name type in the full path you stored the Update Wallpapers script (i.e. \\FQDN\netlogon\Update Wallpapers.ps1), next add another script name again, this time type the full path for the boot script (i.e. C:\Program Files\SchoolName\Wallpaper\Boot Info.ps1).[/size]<br />
</li><li>[size=1]Go to User Configuration -&gt; Policies -&gt; Administrative Templates -&gt; Control Panel -&gt; Personalization -&gt; Force a specific default lock screen and logon image, and enable the policy, specifying the location as: <div>[Code]C:\Windows\System32\oobe\info\backgrounds\backgroundDefault.jpg[/Code]</div><p>[/size]<br />
</p></li></ol><p></p>]]></description><guid isPermaLink="false">1133</guid><pubDate>Tue, 06 Nov 2018 15:52:13 +0000</pubDate></item><item><title>OLD - Office 365 (Click To Run) - (407) Proxy Authentication Required Error</title><link>https://www.edugeek.net/blogs/entry/1123-old-office-365-click-to-run-407-proxy-authentication-required-error/</link><description><![CDATA[<p>Please see: <a href="https://github.com/DJ-1701/407WorkAround" rel="external nofollow">https://github.com/DJ-1701/407WorkAround</a> for latest instructions.</p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p>
<span style="font-size:8px;">So, you've followed the instructions for deploying Office 365 Pro Plus with Device Based Activation... most likely from an online instruction, such as </span><a href="https://sysadminedu.wordpress.com/2017/01/07/step-by-step-guide-to-deploying-office-365-pro-plus-with-device-based-activation-with-sccm/" rel="external nofollow"><span style="font-size:8px;">this awesome one</span></a><span style="font-size:8px;">… but, when you come to running the OPPTransition.exe you get a problem that looks a little like this one...</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
</span></p><pre class="ipsCode">C:\O365&gt;OPPTransition.exe -Tenant TENANTUUID -Key KEYUUID -Domain contoso.onmicrosoft.com
00:00:00 | OPPTransition started - 1.1.12.95
00:00:00 | Reading arguments
00:00:01 | Args: -tenant TENANTUUID -domain contoso.onmicrosoft.com
00:00:01 | Args Valid
00:00:01 | Nonce: RANDOMTEXTHERE
00:00:01 | Start not logged
00:00:01 | One or more errors occurred.
00:00:01 | System.AggregateException: One or more errors occurred. ---&gt; System.Net.Http.HttpRequestException: An error occurred while sending the request. ---&gt; System.Net.WebException: The remote server returned an error: (407) Proxy Authentication Required.
  at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
  at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
  --- End of inner exception stack trace ---
  --- End of inner exception stack trace ---
  at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
  at OPP_Transition.HttpHelperClient.GetResponseWithStatus(String Uri, Status Status)
---&gt; (Inner Exception #0) System.Net.Http.HttpRequestException: An error occurred while sending the request. ---&gt; System.Net.WebException: The remote server returned an error: (407) Proxy Authentication Required.
  at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
  at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
  --- End of inner exception stack trace ---&lt;---

00:00:02 | PreflightCheck failed - wait: 505</pre><div></div><p></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
The problem is that you're using an AD user based web filtering system, and the program is unable to transfer information about who is logged on to authenticate to the proxy server... So, how do you get around that?</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
If you edit the Dot Net machine.config file (i.e. C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config) you can add a section in to place a proxy server that does not use AD based filtering. Before the &lt;/configuration&gt; section, enter the following line, changing PROXYDETAILSHERE:PORT with your non AD user based web filtering system and proxy.</span></p><p><span style="font-size:8px;">
&lt;system.net&gt;&lt;defaultProxy enabled="true" useDefaultCredentials="true"&gt;&lt;proxy usesystemdefault="true" proxyaddress="</span><span style="font-size:8px;"><strong>PROXYDETAILSHERE:PORT</strong></span><span style="font-size:8px;">" bypassonlocal="true"/&gt;&lt;/defaultProxy&gt;&lt;/system.net&gt;</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Although, I find it's easier to do this in a script, and to reset it back afterwards (just in case).</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
</span></p><pre class="ipsCode">$OriginalData = Get-Content("C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config")
$OriginalEnd = '&lt;/configuration&gt;'
$TempEnd = '&lt;system.net&gt;&lt;defaultProxy enabled="true" useDefaultCredentials="true"&gt;&lt;proxy usesystemdefault="true" proxyaddress="[b]PROXYDETAILSHERE:PORT[/b]" bypassonlocal="true"/&gt;&lt;/defaultProxy&gt;&lt;/system.net&gt;&lt;/configuration&gt;'
$TempData = $OriginalData -replace $OriginalEnd,$TempEnd

If ((Get-DAConnectionStatus).Status -ne "ConnectedRemotely")
{
   If (!($OriginalData -like "*proxyaddress=*"))
   {
       If ($OriginalData -like "&lt;/configuration&gt;")
       {
           Set-Content -Path "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config" -Value $TempData
       }
   }
}
.\OPPTransition.exe -Tenant [b]TENANTUUID[/b] -Key [b]KEYUUID[/b] -Domain [b]DOMAIN[/b]
Set-Content -Path "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config" -Value $OriginalData
</pre><div></div>]]></description><guid isPermaLink="false">1123</guid><pubDate>Mon, 21 May 2018 11:52:33 +0000</pubDate></item><item><title>OLD - Deploying Solus via powershell script</title><link>https://www.edugeek.net/blogs/entry/1108-old-deploying-solus-via-powershell-script/</link><description><![CDATA[<p><a href="https://www.edugeek.net/forums/enterprise-software/205256-sccm-deploying-solus-3-sims-net.html#post1758080" rel="">http://www.edugeek.net/forums/enterprise-software/205256-sccm-deploying-solus-3-sims-net.html#post1758080</a></p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p>
<span style="font-size:8px;">Due to strange issues pushing out the Solus agent from the Solus server, I have decided to take a leaf out of  <a contenteditable="false" rel="" href="https://www.edugeek.net/profile/34358-boredguy/" data-mentionid="34358" data-ipshover-target="https://www.edugeek.net/profile/34358-boredguy/?do=hovercard" data-ipshover="">@Boredguy</a>'s book and not bother pushing out from the server console... but instead deploy it with a script which records the GUID in a CSV file for easy reinstallation.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Notes:</span></p><p><span style="font-size:8px;">
The following is setup for a 64 Bit Windows OSes, but can be modified to work with 32 Bit by adding a few lines of code and the installer. If you can not find a copy of the Solus agent on your server, you can go into Solus Deployment Service, click Settings, SOLUS3, SOLUS, Export agent installer.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Let's get started...</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
In a new folder on your software deployment server share, create a folder called Solus and copy the following items:</span></p><p><span style="font-size:8px;">
Solus3.Keys.DeploymentService.Public.xml (From the Solus Server)</span></p><p><span style="font-size:8px;">
SOLUS3AgentInstaller_x64.msi (From the Solus Server)</span></p><p><span style="font-size:8px;">
Agents.csv (new blank file, needs user write permissions to this file only)</span></p><p><span style="font-size:8px;">
SolusInstaller.ps1 (i.e. coding below).</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
Coding note:</span></p><p><span style="font-size:8px;">
1) Replace \\DEPLOYMENT-SERVER-HERE\SHARE-HERE$ with your Deployment share that holds the Solus folder you created.</span></p><p><span style="font-size:8px;">
2) Replace SOLUS-SERVER-HERE with your Solus Server Name.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
PowerShell code for SolusInstaller.ps1:</span></p><p><span style="font-size:8px;">
</span></p><pre class="ipsCode">
$Found=$false
$CSV = "\\DEPLOYMENT-SERVER-HERE\SHARE-HERE$\Solus\Agents.csv"
$SolusAgentDataList=IMPORT-CSV $CSV -Header ("ID","Name")
$GUID=[system.GUID]::NewGuid().ToString()
$ComputerName = (Get-Childitem env:computername).Value
ForEach ($SolusAgentDataItem in $SolusAgentDataList)
{
   If ($SolusAgentDataItem.Name -eq $ComputerName)
   {
       $Found=$true
       $GUID=$SolusAgentDataItem.ID
   }
}
If (!$Found)
{
   Add-Content $CSV "$GUID,$ComputerName`n"
}
&amp;msiexec.exe /i `"\\DEPLOYMENT-SERVER-HERE\SHARE-HERE$\Solus\SOLUS3AgentInstaller_x64.msi`" AGENTSERVICEADDRESS=`"net.tcp://localhost:52966`" AGENTID=$GUID DEPLOYMENTSERVERADDRESS=`"net.tcp://SOLUS-SERVER-HERE:52965`"  RSAKEYPATH=`"\\DEPLOYMENT-SERVER-HERE\SHARE-HERE$\Solus`" /qn /l*v C:\solus.log
Start-Sleep -s 5
</pre><div></div><p></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
To ensure you reuse the same GUID, and get your SIMS/FMS/Discover automatically reinstalled when you rebuild your PC, you can get existing Solus agent GUIDs by looking at AGENTID located in HKEY_LOCAL_MACHINE\SOFTWARE\CCS\SOLUS3\Agent and adding manually to the CSV file in the format.</span></p><p><span style="font-size:8px;">
</span></p><pre class="ipsCode">01234567-89ab-cdef-0123-456789abcdef,Computer-Name-Here
</pre><div></div><p></p><p><span style="font-size:8px;">
with a new line at the end.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
When the script is run on any machine with a computer name that </span><span style="font-size:8px;"><strong>hasn't been recorded</strong></span><span style="font-size:8px;"> in the CSV file, as long as you have given the Installer write permissions to the CSV file, a new GUID and the computer name will be added into the CSV file. You can then go on Solus and assigned SIMS/FMS/Discover to the Agent.</span></p><p><span style="font-size:8px;"> </span></p><p><span style="font-size:8px;">
When the script is run on any machine with a computer name that </span><span style="font-size:8px;"><strong>IS recorded</strong></span><span style="font-size:8px;"> in the CSV file, the GUID is picked up from the CSV file and Solus will install with the software you had previously specified.</span></p>]]></description><guid isPermaLink="false">1108</guid><pubDate>Fri, 24 Nov 2017 11:57:45 +0000</pubDate></item><item><title>Sites requiring bypass to SSL Interception</title><link>https://www.edugeek.net/blogs/entry/1061-sites-requiring-bypass-to-ssl-interception/</link><description><![CDATA[<p>One of the schools I look after has SSL Interception in the form of NetASQ (aka StormShield) to protect from particular content. I thought making a list would be helpful to anyone else having problems with certain sites or technology.</p><p> </p><p>
This is a list of addresses I had to request to bypass the SSL Interception certificate to function correctly.</p><p> </p><p>
<a href="https://portal.office.com" rel="external nofollow">https://portal.office.com</a></p><p>
<a href="https://outlook.office.com" rel="external nofollow">https://outlook.office.com</a></p><p>
<a href="https://www.amazon.co.uk" rel="external nofollow">https://www.amazon.co.uk</a></p><p>
<a href="https://www.sainsburys.co.uk" rel="external nofollow">https://www.sainsburys.co.uk</a></p><p>
<a href="https://www.webex.com" rel="external nofollow">https://www.webex.com</a></p><p>
<a href="https://serco.webex.com" rel="external nofollow">https://serco.webex.com</a></p><p>
<a href="https://global-nebulai.webex.com" rel="external nofollow">https://global-nebulai.webex.com</a></p><p>
<a href="https://www.nwolb.com" rel="external nofollow">https://www.nwolb.com</a></p><p>
<a href="https://securenetplus.swgfl.org.uk" rel="external nofollow">https://securenetplus.swgfl.org.uk</a></p><p>
<a href="https://evolve.edufocus.co.uk" rel="external nofollow">https://evolve.edufocus.co.uk</a></p><p>
<a href="https://cdn.musicexpress.co.uk" rel="external nofollow">https://cdn.musicexpress.co.uk</a> (Note: Amazon Hosting range had to be unblocked as well for this to work.)</p><p>
<a href="https://www.musicexpress.co.uk" rel="external nofollow">https://www.musicexpress.co.uk</a> (Note: Amazon Hosting range had to be unblocked as well for this to work.)</p><p> </p><p>
ap.nvc.enGB.nuancemobility.net via port 443 (Dragon Dictation iOS App deliberately does not use the HTTPS protocol to transmit data on this port, so if any sort of protocol analysis/filtering is taking place, the app fails.)</p>]]></description><guid isPermaLink="false">1061</guid><pubDate>Tue, 24 May 2016 14:57:41 +0000</pubDate></item><item><title>Robocopy Check E-mail</title><link>https://www.edugeek.net/blogs/entry/1060-robocopy-check-e-mail/</link><description><![CDATA[<p>Robocopy is a great command for backing up data between drives or across the network on a scheduled basis.</p><p> </p><p>
Generally I create a batch file with commands like the following to mirror data over night when no one (ok, nearly no one) is accessing the content.</p><p> </p><p>
</p><pre class="ipsCode">
E:
CD\
robocopy "E:\SharedTeacher$" "\\AAA-MS-XX\Backup$\Teachers$" /MIR /R:1 /W:1 /NP &gt; "E:\Logs\Teachers to MSXX.log"
robocopy "E:\SharedAdmin$" "\\AAA-MS-XX\Backup$\Admin$" /MIR /R:1 /W:1 /NP &gt; "E:\Logs\Admin to MSXX.log"
</pre><div></div><p></p><p> </p><p>
As you can see, I output the results to a file, so I can review. Problem is, the more Robocopy commands that are used, across different servers, the more files I have to check through where most of the time the process would have been successful... Wouldn't it be much simpler if a brief summary was e-mailed to us...</p><p> </p><p>
If you have an SMTP relay setup, excellent you're most of the way there already, if not, this is how I set one up on Windows 2012 R2 (and can be done on previous versions back to at least 2003, though instructions may vary).</p><p> </p><p>
Install the Server feature 'SMTP Relay' and accept all the dependencies.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2016_05/000.png.0b26ebac71039087fa4b36b3053c8ad2.png" data-fileid="357" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="000.png.0b26ebac71039087fa4b36b3053c8ad2.png" data-fileid="357" data-src="https://www.edugeek.net/uploads/monthly_2016_05/000.png.0b26ebac71039087fa4b36b3053c8ad2.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Open Internet Information Services (IIS) 6.0 Manager, right click on [sMTP Virtual Server] and select Properties.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2016_05/001.png.a8350b994123e5bddae99eb551c6a5cb.png" data-fileid="358" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="001.png.a8350b994123e5bddae99eb551c6a5cb.png" data-fileid="358" data-src="https://www.edugeek.net/uploads/monthly_2016_05/001.png.a8350b994123e5bddae99eb551c6a5cb.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Click on the Advanced tab.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2016_05/002.png.b6b6ad8af98fa8f6547de3682937675f.png" data-fileid="359" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="002.png.b6b6ad8af98fa8f6547de3682937675f.png" data-fileid="359" data-src="https://www.edugeek.net/uploads/monthly_2016_05/002.png.b6b6ad8af98fa8f6547de3682937675f.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Ensure you have a port 25 setup for incoming mail.</p><p>
Note: You may need to add a Windows Firewall rule to allow traffic to the server on that port.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2016_05/003.png.b8eee7cb5508f3f4a154652c00d947ee.png" data-fileid="360" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="003.png.b8eee7cb5508f3f4a154652c00d947ee.png" data-fileid="360" data-src="https://www.edugeek.net/uploads/monthly_2016_05/003.png.b8eee7cb5508f3f4a154652c00d947ee.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
On the Access tab, click Authentication.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2016_05/004.png.e93649682962af87826b7086851077a6.png" data-fileid="361" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="004.png.e93649682962af87826b7086851077a6.png" data-fileid="361" data-src="https://www.edugeek.net/uploads/monthly_2016_05/004.png.e93649682962af87826b7086851077a6.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Tick Anonymous access and OK.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2016_05/005.png.c034d842b409714878db0917a0673023.png" data-fileid="362" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="005.png.c034d842b409714878db0917a0673023.png" data-fileid="362" data-src="https://www.edugeek.net/uploads/monthly_2016_05/005.png.c034d842b409714878db0917a0673023.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Click the Connection button and list the Server IP Address you wish to send email via this server. Click OK.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2016_05/006.png.ffb35399aa3175fb3ab212ffce1829cc.png" data-fileid="363" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="006.png.ffb35399aa3175fb3ab212ffce1829cc.png" data-fileid="363" data-src="https://www.edugeek.net/uploads/monthly_2016_05/006.png.ffb35399aa3175fb3ab212ffce1829cc.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Click the Relay button and list the Server IP Address you wish to send email via this server. Click OK.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2016_05/007.png.a1541ba038ec1e52463c6576bf26c6f8.png" data-fileid="364" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="007.png.a1541ba038ec1e52463c6576bf26c6f8.png" data-fileid="364" data-src="https://www.edugeek.net/uploads/monthly_2016_05/007.png.a1541ba038ec1e52463c6576bf26c6f8.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Make sure you have sensible limits on the Messages tab.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2016_05/008.png.3aca5773dce1ba435b96ebd251815098.png" data-fileid="365" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="008.png.3aca5773dce1ba435b96ebd251815098.png" data-fileid="365" data-src="https://www.edugeek.net/uploads/monthly_2016_05/008.png.3aca5773dce1ba435b96ebd251815098.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Click the Delivery tab, followed by the Outbound Security button.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2016_05/009.png.54b21f2b3d9f3754003f5a08ecbf249f.png" data-fileid="366" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="009.png.54b21f2b3d9f3754003f5a08ecbf249f.png" data-fileid="366" data-src="https://www.edugeek.net/uploads/monthly_2016_05/009.png.54b21f2b3d9f3754003f5a08ecbf249f.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Select Basic authentication and type an e-mail address you wish the information to be sent from, as well as the password. Click OK.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2016_05/010.png.91184d0f097f9f38d3976a051eb8adf5.png" data-fileid="367" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="010.png.91184d0f097f9f38d3976a051eb8adf5.png" data-fileid="367" data-src="https://www.edugeek.net/uploads/monthly_2016_05/010.png.91184d0f097f9f38d3976a051eb8adf5.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
In Advanced, type the FQDN of your local server. For smart host, type your smtp address. In this example we are sending out to our Office 365 account, so the smart host is: SMTP.office365.com</p><p> </p><p>
Now that you have an SMTP relay up and running, we will want to create a script to scan the robocopy log files and email if there is an issue... here's one I made earlier...</p><p> </p><p>
</p><pre class="ipsCode">
$Computername = (Get-Childitem env:computername).Value
$Log = ""
$DetectedFailure = 0
# Mail relay settings (The local server configured to send an e-mail).
$SMTPSERVER = "ms00.internal.school.county.sch.uk"
$MAILFROM = "server@school.county.sch.uk"
$MAILTO = "ictsupport@school.county.sch.uk"
$MESSAGE = ""

function funcResultCheck ()
{
   $DirError = 9
   $FileError = 9
   $ByteError = 9

   $Data = Get-Content($Log)

       ForEach ($Line in $Data)
       {
           # Dirs - Manual Error Testing Comment
           # 0                     1Total   2Copied  3Skipped 4Mismatch   5FAILED   6Extras
           #$Line = "    Dirs :         1         0         1         0         0         0"
           If ($Line.Contains("Dirs :"))
           {
               $Line = $Line -replace "Dirs :",""
               $Line = $Line -replace " ",";"
               Do
               {
                   $Line = $Line -replace ";;",";"
               }While ($Line.Contains(";;"))
               $DirValues = $Line -split ";"
               $DirError = 9
               If ($DirValues.Count -eq 7)
               {
                   $DirError = [int]$DirValues[5]
                   If (!($?)) {$DirError = 9}
               }
           }

           # Files - Manual Error Testing Comment
           # 0                     1Total   2Copied  3Skipped 4Mismatch   5FAILED   6Extras
           #$Line = "   Files :         1         0         0         0         1         0"
           If ($Line.Contains("Files :"))
           {
               $Line = $Line -replace "Files :",""
               $Line = $Line -replace " ",";"
               Do
               {
                   $Line = $Line -replace ";;",";"
               }While ($Line.Contains(";;"))
               $FileValues = $Line -split ";"
               $FileError = 9
               If ($FileValues.Count -eq 7)
               {
                   $FileError = [int]$FileValues[5]
                   If (!($?)) {$FileError = 9}
               }
           }

           # Bytes - Manual Error Testing Comment
           # 0                     1Total   2Copied  3Skipped 4Mismatch   5FAILED   6Extras
           #$Line = "   Bytes :    15.0 k         0         0         0    15.0 k         0"
           If ($Line.Contains("Bytes :"))
           {
               $Line = $Line -replace "Bytes :",""
               $Line = $Line -replace "[a-z]",""
               $Line = $Line.TrimEnd()
               $Line = $Line -replace " ",";"
               Do
               {
                   $Line = $Line -replace ";;",";"
               }While ($Line.Contains(";;"))
               $ByteValues = $Line -split ";"
               $ByteError = 9
               If ($ByteValues.Count -eq 7)
               {
                   $ByteError = [int]$ByteValues[5]
                   If (!($?)) {$ByteError = 9}
               }
           }
       }

   $TotalError = $DirError + $FileError + $ByteError

   If ($TotalError -eq 0)
   {
       Write-Host "Successful! :D"
       $MESSAGE = $MESSAGE + $Log + " - Successful !`n"
   }
   Else
   {
       Write-Host "Unsuccessful! D:"
       $MESSAGE = $MESSAGE + $Log + " - FAILED! D:!!!`n"
       $DetectedFailure = 1
   }
}

$Log = "E:\Logs\Teachers to MSXX.log"
. funcResultCheck
$Log = "E:\Logs\Admin to MSXX.log"
. funcResultCheck

#Set subject message based on value of text in ResultsEmail
if($DetectedFailure -eq 1){$MAILSUBJECT = "$Computername Backup FAILURE"}else {$MAILSUBJECT = "$Computername Backup Success"}

$MESSAGE = "This is a backup message from " + $Computername + ".`n`n$Computername Backup has been Processed. Results as follows:`n`n" + $MESSAGE + "`nServer Automated Message"
Send-MailMessage -To "$MAILTO" -From "$MAILFROM" -Subject "$MAILSUBJECT" -Body "$MESSAGE" -SmtpServer "$SMTPSERVER"
</pre><div></div><p></p><p> </p><p>
Remember to replace the value set for:</p><p>
- $SMTPSERVER with your FQDN or IP Address of your SMTP relay server.</p><p>
- $MAILFROM with the email account you will be sending the message from (same as the one used on the relay server).</p><p>
$MAILTO with the e-mail address of who you want the report sent to.</p><p>
$Log with the name of the log file you wish to check.</p><p> </p><p>
After specifing the log file to check, always make sure there is a new line with</p><p>
</p><pre class="ipsCode">
. funcResultCheck
</pre><div></div><p></p><p>
This will tell the script to check the file to see if it failed to copy any file.</p><p> </p><p>
You can run the script manually to test the result.</p><p> </p><p>
When you are happy that everything has been setup, you can go back to your batch file running robocopy and at the end type this line (modifying for path an script name of course).</p><p> </p><p>
</p><pre class="ipsCode">
powershell.exe -noprofile -executionpolicy bypass -file "E:\Tasks\RoboCheck.ps1"
</pre><div></div><p></p>]]></description><guid isPermaLink="false">1060</guid><pubDate>Thu, 19 May 2016 10:46:50 +0000</pubDate></item><item><title>MDT for Windows 10 (Basic Functionality)</title><link>https://www.edugeek.net/blogs/entry/1049-mdt-for-windows-10-basic-functionality/</link><description><![CDATA[<p>This assumes no knowledge of MDT and no prior installation and is one of many ways of configuration.</p><p> </p><p>
First of all, download the following:</p><p> </p><p>
ADK for Windows 10</p><p>
<a href="https://msdn.microsoft.com/en-us/windows/hardware/dn913721.aspx#adkwin10" rel="external nofollow">https://msdn.microsoft.com/en-us/windows/hardware/dn913721.aspx#adkwin10</a></p><p> </p><p>
MDT 2013 Update 1</p><p>
<a href="https://www.microsoft.com/en-us/download/details.aspx?id=48595" rel="external nofollow">https://www.microsoft.com/en-us/download/details.aspx?id=48595</a></p><p> </p><p>
Windows 10 Pro/Edu/Ent ISO/DVD</p><p>
<a href="https://www.microsoft.com/Licensing/servicecenter/default.aspx" rel="external nofollow">https://www.microsoft.com/Licensing/servicecenter/default.aspx</a></p><p> </p><p>
<span style="text-decoration:underline;">ADK</span></p><p>
On the server you have designated for MDT, install ADK for Windows 10 to a directory of your choosing, selecting No to the Participation for the Windows Kits. The main feature you want to install is the Deployment Tools and the Windows Preinstallation Environment (Windows PE), you can if you wish install other elements if you will be experimenting with them later.</p><p> </p><p>
<span style="text-decoration:underline;">MDT - Deployment Share Creation</span></p><p>
Run the installer, select a directory of your choosing to install MDT. For the Customer Experience Improvement Program select 'I don't want to join the program at this time'.</p><p> </p><p>
Once MDT has installed, launch Deployment Workbench, right click and select New Deployment Share. When asked for a path, enter a path of X:\DeploymentShare (where X is a drive letter of plenty of space for storing the OS and any future drivers). For this instruction, it will be assumed you will have the Share name of DeploymentShare$.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2015_12/MDT012.png.02a45ac53748e752814b8121b7dd81aa.png" data-fileid="337" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="MDT012.png.02a45ac53748e752814b8121b7dd81aa.png" data-fileid="337" data-src="https://www.edugeek.net/uploads/monthly_2015_12/MDT012.png.02a45ac53748e752814b8121b7dd81aa.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
You will be asked to customise the default behaviour for MDT. The settings I have chosen in this example with the reasons are as follows.</p><p> </p><p>
Ask if a computer backup should be performed. -  No (As I will only be building or reinstalling PCs).</p><p>
Ask for a product key - No (As I use KMS).</p><p>
Ask to set the local Administrator password - No (As I will be setting this on the Task Sequence (shown later).</p><p>
Ask if an image should be captured - No (As I will be deploying fresh installations of Windows from the media and then updating).</p><p>
Ask if BitLocker should be enabled - No (As I can set BitLocker in the Task Sequence if required).</p><p> </p><p>
You can then finish the New Deployment Share Wizard.</p><p> </p><p>
<span style="text-decoration:underline;">MDT - Updating the Deployment Share Properties</span></p><p>
Right click on the Deployment Share and select Properties.</p><p> </p><p>
If you wish to enable monitoring on the state of the builds, go to the Monitoring tab and select the Enable monitoring tick box.</p><p> </p><p>
If you won't be booting any computers off of a CD to connect to the network deployment share, go to the Windows PE tab and deselect the Generate a Lite Touch bootable ISO image. Change the Platform at the top and repeat the settings for the x64 image.</p><p> </p><p>
On the Rules tab, create a couple of new lines, then enter any custom settings you wish. The settings I use are below.</p><p> </p><p>
</p><pre class="ipsCode">
SkipLocaleSelection=YES
UserLocale=en-GB
SystemLocale=en-GB
UIlanguage=en-US
KeyboardLocale=0809:00000809
TimeZoneName=GMT Standard Time
SkipTimeZone=YES

SkipAppsOnUpgrade=YES
SkipUserData=YES
SkipSummary=YES

WSUSServer=http://WIN-MS-01:8530
MachineObjectOU=OU=Workstations,DC=Horcrux,DC=Voldemort,DC=JKR,DC=Sch,DC=UK
JoinDomain=Horcrux

FinishAction=REBOOT
</pre><div></div><p></p><p> </p><p>
The top box of text sets the local to the UK. The second section of code disables screens such as the USMT as I won't be needing it. The third lot of settings specifies the WSUS server, the default location where I want to add computers and the domain name. Last but not least after a successful install, I want the PC to reboot so users can start using the machine (as I have a GPO with all the settings I want for the PC in the OU we are creating this in).</p><p> </p><p>
Click on the Bootstrap.ini button.</p><p> </p><p>
Under the [Default] header, enter the following:</p><p> </p><p>
</p><pre class="ipsCode">
KeyboardLocalePE=0809:00000809
SkipBDDWelcome=YES
DeployRoot=\\DeploymentServer\DeploymentShare$
</pre><div></div><p></p><p> </p><p>
This sets the Windows PE keyboard to English UK (so the " and @ keys are mapped to the correct place!). Skips the first page welcoming you to Windows PE and immediately presents you with the username and password field. DeploymentRoot defines the location to pick up the Custom Settings file we updated in the previous section, the task sequences and the Operating Systems. Save the file and click ok.</p><p> </p><p>
Note: Whenever you change the Bootstrap.ini, add replace the Windows PE with one from an updated ADK or add new network or storage drivers, you will need to regenerate the WDS wim. This will be discussed later.</p><p> </p><p>
<span style="text-decoration:underline;">MDT - Adding the Operating System</span></p><p><span style="text-decoration:underline;">
</span>In the Deployment Share section, right click on Operating Systems and select Import Operating System. Either mount the Windows 10 ISO image (double click in Server 2012) or put the DVD in the drive.</p><p> </p><p>
Select 'Full set of source files' and click Next (you could just select the WIM file, but I like to make sure I have all the files, just in case). Select the Drive letter the Windows 10 ISO/DVD is on and click Next.</p><p> </p><p>
Give the OS a relevant name or left with the default and click Next. On the Summary window, click Next and once Finished, click Finish.</p><p> </p><p>
<span style="text-decoration:underline;">MDT - Adding a Task Sequence</span></p><p><span style="text-decoration:underline;">
</span>In the Deployment Share section, right click on Task Sequences and select New Task Sequence. Enter a Task sequence ID and name, for example ID: 10x64 Name: Windows 10 x64 and click Next. As this Task Sequence will be for building a new PC, select the Template 'Standard Client Task Sequence' and click Next.</p><p> </p><p>
Select the OS you wish to deploy and click Next. For the Product Key section, if you are using KMS to activate Windows, just select 'Do not specify a product key at this time' and click Next. For the full name and organisation, type your School/Business name, you can also customise the default Internet Explorer Home Page if you wish and click Next.</p><p> </p><p>
Enter a local Administrator account password you want on the machine and click Next. Click Next on the Summary and Finish on the Confirmation.</p><p> </p><p>
<span style="text-decoration:underline;">MDT - Updating the Task Sequence</span></p><p><span style="text-decoration:underline;">
</span>Double click on the Task Sequence you have just created.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2015_12/MDT036.png.f79f161925dfc029c5240e46e2518195.png" data-fileid="345" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="MDT036.png.f79f161925dfc029c5240e46e2518195.png" data-fileid="345" data-src="https://www.edugeek.net/uploads/monthly_2015_12/MDT036.png.f79f161925dfc029c5240e46e2518195.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p> </p><p>
As we want this sequence to always format the machine, we are going to move a few tasks. Expand the Preinstall section, followed by the New Computer only section and move the Validate, Format and Partition Disk (BIOS), Format and Partition Disk (UEFI) and Copy scripts tasks up above the New Computer only section and underneath the Gather local only section.</p><p> </p><p>
As part of the build process, I want the machine to connect to our WSUS server to make sure it's up to date. To do this I will expand the State Restore section and click on the Windows Update (Pre-Application Installation) task, click on Options, and untick the 'Disable this step' and make sure 'Continue on error' is ticked. In case I decide to use MDT to deploy any applications in the future, I will also make these changes to the Windows Update (Post-Application Installation) task.</p><p> </p><p>
As part of the build process, I want to add Dot Net 3.5, as some of my applications require it. To do this I go to the Custom Tasks section and click 'Add', 'General', 'Run Command Line'. On the Properties tab I change the name of the task to Dot Net 3.5 and for the command line I type:</p><p> </p><p>
</p><pre class="ipsCode">
Dism /online /enable-feature /featurename:NetFX3 /All /Source:"\\DeploymentServer\DeploymentShare$\Operating Systems\Windows 10 Education VL 2015-11 x64\sources\sxs" /LimitAccess
</pre><div></div><p></p><p> </p><p>
As we have some PowerShell scripts which we like to run, I want to change the PowerShell execution policy.  To do this I go to the Custom Tasks section and click 'Add', 'General', 'Run Command Line'. On the Properties tab I change the name of the task to Enable PowerShell Scripts and for the command line I type:</p><p> </p><p>
 </p><pre class="ipsCode">
powershell.exe Set-ExecutionPolicy RemoteSigned
</pre><div></div><p></p><p> </p><p>
Note: If I want to I could also make a custom batch file in a folder on <a rel="">\\DeploymentServer\DeploymentShare$\Scripts</a> and run this from a task <span style="color:#222222;"><span style="font-family:Tahoma;">sequence</span></span>. if I want to refer to the scripts folder within a task <span style="color:#222222;"><span style="font-family:Tahoma;">sequence</span></span> I can used the variable %SCRIPTROOT% (i.e. %SCRIPTROOT%\Custom\School.cmd).</p><p> </p><p>
<span style="text-decoration:underline;">Creating/Updating the Boot WIMs.</span></p><p>
Right click on the Deployment Share and select Update Deployment Share. Select the option to Completely regenerate the boot images and click Next. Click Next on the Summary. Once the process is complete (it may take some time), click Finish.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2015_12/tumblr_kz1wzbwyt11qzeixco1_400.jpg.52356bf2203d05867730a9a769ada579.jpg" data-fileid="338" data-fileext="jpg" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="tumblr_kz1wzbwyt11qzeixco1_400.jpg.52356bf2203d05867730a9a769ada579.jpg" data-fileid="338" data-src="https://www.edugeek.net/uploads/monthly_2015_12/tumblr_kz1wzbwyt11qzeixco1_400.jpg.52356bf2203d05867730a9a769ada579.jpg" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Note: If you need to change Bootstrap.ini, add any Network Drivers or Storage Drivers to the drivers folder, you will need to follow the above so the Windows PE environment can access these devices or changes.</p><p> </p><p>
<span style="text-decoration:underline;">WDS - Setup</span></p><p><span style="text-decoration:underline;">
</span>On your MDT server, add the Server Role of Windows Deployment Services, and accept the defaults. Once installed, launch Windows Deployment Services, right click on the Server object and click Configure Server. On the options, select <span style="color:#222222;"><span style="font-family:Tahoma;">Integrated</span></span> with Active Directory, set the drive letter for the path to the same drive letter used for the MDT Deployment Share (i.e. X:\RemoteInstall instead of C:\RemoteInstall).</p><p> </p><p>
On the Proxy DHCP window, if you are running DHCP on the same server tick both boxes, if not untick them and click Next. Select Respond to all client computers (known and unknown) and click Next. Once the Service has installed, click Finish.</p><p> </p><p>
<span style="text-decoration:underline;">WDS - Boot Images</span></p><p>
Under the Server, right click the Boot Images folder and select 'Add Boot Image...'. Select the file X:\DeploymentShare\Boot\LiteTouchPE_x86.wim and click Next, you can change the display name if you wish and click Next, Next and eventually Finish.</p><p> </p><p>
Repeat the above for the X:\DeploymentShare\Boot\LiteTouchPE_x64.wim file.</p><p> </p><p>
<span style="text-decoration:underline;">Installing your PC</span></p><p><span style="text-decoration:underline;">
</span>To install your PC, enable network boot and start up your machine.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2015_12/INS001.png.00af08b6dc373aaf3574021cbeba3170.png" data-fileid="339" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="INS001.png.00af08b6dc373aaf3574021cbeba3170.png" data-fileid="339" data-src="https://www.edugeek.net/uploads/monthly_2015_12/INS001.png.00af08b6dc373aaf3574021cbeba3170.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
When prompted, press F12.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2015_12/INS002.png.9c12f4179eb1daccd1db53a900d02578.png" data-fileid="340" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="INS002.thumb.png.b694608a69454cde0a3d9d1836a634a8.png" data-fileid="340" data-src="https://www.edugeek.net/uploads/monthly_2025_03/INS002.thumb.png.b694608a69454cde0a3d9d1836a634a8.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
On some computers you may only see the x86 image or x64 boot wim files. Select one of the two files to continue.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2015_12/INS003.png.55d82ce45e2fab26b17b40bb53c59877.png" data-fileid="341" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="INS003.thumb.png.fa8de485c1812d82a3bc396e9e1145bb.png" data-fileid="341" data-src="https://www.edugeek.net/uploads/monthly_2025_03/INS003.thumb.png.fa8de485c1812d82a3bc396e9e1145bb.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Enter your build account (or admin account), username, password and domain to install and click OK.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2015_12/INS004.png.572433cba83df8e34cf1b0454e6de82a.png" data-fileid="342" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="INS004.thumb.png.ec6078e5c786cc1569569f675565af74.png" data-fileid="342" data-src="https://www.edugeek.net/uploads/monthly_2025_03/INS004.thumb.png.ec6078e5c786cc1569569f675565af74.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Select the Windows version you want to install from fresh on your machine and click Next.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2015_12/INS005.png.89e7fe4fc31bf63666915fbac831fe26.png" data-fileid="343" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="INS005.thumb.png.63992348f56c9fd65ec7e7b9d717bba4.png" data-fileid="343" data-src="https://www.edugeek.net/uploads/monthly_2025_03/INS005.thumb.png.63992348f56c9fd65ec7e7b9d717bba4.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
Change the computer name, and if you want the PC in a different OU, amend the OU details.</p><p> </p><p>
<a class="ipsAttachLink ipsAttachLink_image" href="https://www.edugeek.net/uploads/monthly_2015_12/INS006.png.780ddc20cd2283df186dae12fdd13b96.png" data-fileid="344" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" alt="INS006.thumb.png.bb72b7758d19a980fcdfe33abb4a96bf.png" data-fileid="344" data-src="https://www.edugeek.net/uploads/monthly_2025_03/INS006.thumb.png.bb72b7758d19a980fcdfe33abb4a96bf.png" src="https://www.edugeek.net/applications/core/interface/js/spacer.png" /></a></p><p>
The PC will now install. If there are any errors you should get a report at the end.</p><p> </p><p>
<span style="text-decoration:underline;">Extras - </span><span style="text-decoration:underline;"><span style="text-decoration:underline;"><span style="color:#222222;"><span style="font-family:Tahoma;">Security</span></span></span></span></p><p><span style="text-decoration:underline;">
</span>Once you are happy with everything, you can add some security features.</p><p> </p><p>
Using Part 2 - Steps 2 to 9 (excluding LABEL hardyubuntudesktop32 and below) from <a href="http://www.deployvista.com/home/tabid/36/entryid/65/language/en-us/default.aspx" rel="external nofollow">this guide</a>, you can password protect before using the getting the Windows Deployment Services menu. This helps prevent users loading a command prompt or other tools in the Windows PE environment unless they know the password.</p><p> </p><p>
If you want to disable any interaction during the building process, you can add these two lines in the Custom Settings section.</p><p>
DisableTaskMgr=YES</p><p>
HideShell=YES</p><p> </p><p>
<span style="text-decoration:underline;">Extras - Multiple OUs</span></p><p>
If you want to have a selection box of OUs to place the computer in, you can find a guide how to do this here: <a href="https://scriptimus.wordpress.com/2013/02/11/mdt-2012-domainous-list/" rel="external nofollow">https://scriptimus.wordpress.com/2013/02/11/mdt-2012-domainous-list/</a></p><p>
You will need to remove the line MachineObjectOU=... from your Custom Settings file for this to work.</p><p> </p><p>
<span style="text-decoration:underline;">Troubleshooting</span></p><p>
If after entering your username password and domain in Windows PE, if it just hangs there, check to make sure that the DeploymentShare share permission has been set for the user.</p>]]></description><guid isPermaLink="false">1049</guid><pubDate>Fri, 11 Dec 2015 14:41:37 +0000</pubDate></item></channel></rss>
