Microsoft Admin | Network Image Deployment System

NID Demployment System / Microsoft Administrator

Click for Portfolio

I developed Network Image Deployment (NID) as a system to centrally deploy Microsoft operating systems, based off Microsoft’s deployment technologies. Network Image Deployment has been used to deploy computers and servers for companies such as Xerox and The Write Source.

NID can capture, maintain and deploy computer images for a corporate or educational environment. Offline image mounting and updating with hardware independence natively supported allows one central image for each major departmental structure, reducing the costs associated with traditional deployment platforms.

NID is designed to run on a network environment and can be scaled with subnetworks to accommodate data segregation across each of the major departments within the environment.  For off-site or small deployment distributions, NID also includes a DVD Boot compile (for driver injection and custom scripting), turning any two remote client machines into a full scale deployment environment within minutes simply by booting from the DVD.

Functions of Network Image Deployment include:

Major Functions

  • ISO Compile for Remote Deployment
  • Prepare_for_capture
  • Capture
  • Deploy
  • Map_a_drive
  • Boot_DVD
  • Generate_Key
  • Mount_wim
  • Restore_Key
  • Settings
  • Tools
    • Functions to Capture and Deploy Settings

    • capture_settings
    • capture_title
    • deploy_settings
    • deploy_title
    • map_a_drive_settings
    • mount_title
    • mount_wim_settings
    • universal_settings
      • Support Functions

      • capture_image
      • choose_file
      • choose_server
      • deploy_image
      • format_drive
      • generate_log_file
      • generate_log_file_line
      • generate_menu
      • image_selection
      • import_file_selection
      • map_drive
      • mount_wim
      • restore_drive
      • shutdown
      • title_script
      • unmount_wim
        • Documentation Thumbnails

          Click the link at the top of this page for the full documentation manual.

          deployment_notes-page-001 deployment_notes-page-003 deployment_notes-page-002 deployment_notes-page-004 deployment_notes-page-005 deployment_notes-page-006 deployment_notes-page-007 deployment_notes-page-008 deployment_notes-page-009 deployment_notes-page-010 deployment_notes-page-011 deployment_notes-page-012

          Certain examples include:

          Automatic Deployment Based On External Database

          function Auto-Selection {
          param([String]$imagefile="void")
          
          $ErrorActionPreference = "Stop"
          Try {
          	$Networks =  Get-WmiObject Win32_NetworkAdapterConfiguration   -Filter "DHCPEnabled=$True" | ? {$_.IPEnabled}
          	foreach ($Network in $Networks) {
          		$IsDHCPEnabled = $false
          		If($network.DHCPEnabled) {
          		$IsDHCPEnabled = $true
          			}
          			[string[]]$MAC += $Network.MACAddress
          		}
          	if($MAC.Length -ne 0)
          		{
          			Write-Host ("Local MAC Address: " + $MAC)
          		}
          	else 
          		{
          			Write-Host ("Local MAC Address Not Found.")
          			Exit 1001
          		}
          }
          	Catch 
          	{
          		Write-Host ("Local MAC Address Not Found.")
          		Exit 1001
          	}
          
          $MAC_FROM_FILE = @()
          $IMAGE_FROM_FILE = @()
          
          Import-Csv $imagefile |`
              ForEach-Object {
                  $MAC_FROM_FILE += $_.MAC
                  $IMAGE_FROM_FILE += $_.Image
              }
          
          if ($MAC_FROM_FILE -contains $MAC)
              {
          		$Where = [array]::IndexOf($IMAGE_FROM_FILE, $MAC)
          		Write-Host "Image From File: " $IMAGE_FROM_FILE[$Where]
              }
          else 
          	{
          		Write-Host ("MAC Does Not Exist!")
          		Exit 1001
          	}
          
          Clear-Host
          Write-Host $IMAGE_FROM_FILE
          
          }

          User Setup / Variable Designation

          function Set-Variables {
          		Clear-Host
          		Write-Centered "============================================="  "white"
          		Write-Centered "$productTitle $productVersion Setup" "white"
          		Write-Centered "=============================================" "white"
          		Write-Host 
          		Write-Host "Server Connection" -foregroundcolor "green"
          		Write-Host "-----------------" -foregroundcolor "green"
          		Write-Host "[1] Server:	$serverPath"
          		Write-Host "[2] Drive:	$driveLetter"
          		Write-Host "[3] Username:	$mapUser"
          		Write-Host "[4] Password:	********"
          		Write-Host ""
          		Write-Host "[5] Return to Main Menu"
          		Write-Host ""
          		[int]$xMenuChoiceB = 0
          		$xMenuChoiceB = read-host "Enter a value to update"
          		
          		Switch( $xMenuChoiceB ){
          	1{
          		$script:serverPath = read-host "Enter full path to server ('\\server\share')"
          			while ($serverPath.length -le 3) {
          				$script:serverPath = read-host "Enter full path to server again (path too short)"
          				}
          		}
          	2 {
          		$script:driveLetter = read-host "Enter drive letter for mapping (ex. 'q:')"
          			while ($driveLetter.length -ne 2) {
          				$driveLetter = read-host "Please re-enter just a single drive letter (ex. 'q:')"
          				}
          			while (
          				($driveLetter.CompareTo("c:") -eq 0) -or 
          				($driveLetter.CompareTo("d:") -eq 0) -or 
          				($driveLetter.CompareTo("e:") -eq 0) -or
          				($driveLetter.CompareTo("f:") -eq 0) -or
          				($driveLetter.CompareTo("x:") -eq 0)) {
          				$driveLetter = read-host "To avoid conflict, please choose a different drive letter"
          				}
          		}
          	3 {
          		$script:mapUser = read-host "Enter new user"
          			while ($mapUser.length -le 2) {
          				$script:mapUser = read-host "Enter new user again (name too short)"
          				}
          		}
          	4 {
          		$script:mapPassword = read-host "Enter new password"
          			while ($mapPassword.length -le 2) {
          				$mapPassword = read-host "Enter password again (password too short)"
          				}
          		}
          	5 {
          		return
          		}
          	default {
          		Write-Centered "Incorrect Selection Entered" "red"
          		sleep -seconds 2
          		Set-Variables
          		}
          	}
          		
          		Write-Host Updating values...
          		sleep -seconds 1
          		New-Object -TypeName PSCustomObject -Property @{
          			"Product Author" = $productAuthor
          			"Product Title" = $productTitle
          			"Product Build Date" = $productBuildDate
          			"Product Version" = $productVersion
          			"Testing Product Now" = $productTestingNow
          			"Server Path" = $serverPath
          			"Drive Letter" = $driveLetter
          			"Map User" = $mapUser
          			"Map Password" = $mapPassword
          		} | Export-Csv -Path $setupFile2 -NoTypeInformation
          		Set-Variables
          }

          Log Files

          function Generate-Log-File {
          
          Write-Output "========================================================================" | Out-File $logFile -width 120
          Write-Output "Log File	:	$pcHost-$dateStamp.log" | Out-File $logFile -width 120 -Append
          Write-Output "------------------------------------------------------------------------" | Out-File $logFile -width 120 -Append
          Write-Output "Log Date	:	$(get-date)" | Out-File $logFile -width 120 -Append
          Write-Output "App Name	:	$productTitle $productVersion" | Out-File $logFile -width 120 -Append
          Write-Output "App Date	:	Product Build $productBuildDate" | Out-File $logFile -width 120 -Append
          Write-Output "App Author	:	$productAuthor" | Out-File $logFile -width 120 -Append
          Write-Output "Host Name	:	$env:computername" | Out-File $logFile -width 120 -Append
          Write-Output "User Name	:	$env:username" | Out-File $logFile -width 120 -Append
          Write-Output "========================================================================" | Out-File $logFile -width 120 -Append
          
          if (!$?){
          	Write-Host "Error. Could Not Generate Log File." -ForegroundColor "Red"
          	sleep -seconds 30}
          else{
          	Write-Host "$computerHost_$dateStamp.log Log File Generated..."
          	sleep -seconds 1}
          
          #if (!$?){
          #	Generate-Log-File-Line "Type" "Failed."}
          #else{
          #	Generate-Log-File-Line "Type" "Passed."}
          
          }
          
          function Generate-Log-File-Line ($logType,$logText) {
          
          Write-Output "$(get-date -f MM-dd-yyyy_HH_mm_ss)| $logType : $logText" | Out-File $logFile -width 120 -Append
          
          if (!$?){
          	Write-Host "Could not add to log file."
          	sleep -seconds 5}
          else{
          	Write-Host "Logging..."
          	sleep -seconds 1}
          }

          Drive Mapping

          function Map-Drive ($driveLetter,$serverPath,$mapUser,$mapPassword){
          	$logType="MAP DRIVE"
          	[int]$counter
          	Clear-Host
          		if ($driveLetter.length -le 1) {
          			Write-Host "=============================================================="
          			Write-Host "$productTitle $productVersion Map Drive Utility"
          			Write-Host "=============================================================="
          			$driveLetter = read-host "Enter drive letter to map (ex. 'q:')"
          			while ($driveLetter.length -ne 2) {
          				$driveLetter = read-host "Please re-enter just a single drive letter (ex. 'q:')"
          				}
          			while (
          				($driveLetter.CompareTo("c:") -eq 0) -or 
          				($driveLetter.CompareTo("d:") -eq 0) -or 
          				($driveLetter.CompareTo("e:") -eq 0) -or
          				($driveLetter.CompareTo("f:") -eq 0) -or
          				($driveLetter.CompareTo("x:") -eq 0)) {
          				$driveLetter = read-host "To avoid conflict, please choose a different drive letter"
          				}
          			if ($serverPath.length -le 1) {$serverPath = read-host "Enter full path to server ('\\server\share')"}
          			if ($mapUser.length -le 1) {$mapUser = read-host "Enter full username ('domain\user')"}
          			if ($mapPassword.length -le 1) {$mapPassword = read-host -assecurestring "Enter password"}
          			}
          		
          		if ($mapPassword.length -le 1) {
          			Write-Host CREDENTIALS REQUIRED FOR $mapUser.ToUpper TO MAP $serverPath.ToUpper
          			Write-Host "==============================================================="
          			$mapPassword = read-host -assecurestring "Enter password for $mapUser"}
          		
          		Write-Host "Removing $driveLetter if it exists..."
          		$net = new-object -ComObject WScript.Network
          		if (Test-Path -path $driveLetter) {$net.RemoveNetworkDrive("$driveLetter")}
          		Write-Host "Attempting to map $driveLetter to $serverPath ..."
          		$net.MapNetworkDrive("$driveLetter", "$serverPath", $false, "$mapUser", "$mapPassword")
          		
          		if (!$?){
          			$counter++
          			Generate-Log-File-Line $logType "FAILED attempt $counter of 3 to map $serverPath to $driveLetter."
          			Clear-Host
          			if ($counter -eq 1) {
          				Write-Host "Drive could not be mapped! Trying automatic settings again..." -ForegroundColor Red
          				sleep -seconds 5
          				Map-Drive $driveLetter $serverPath $mapUser $mapPassword}
          			
          			if ($counter -eq 2) {
          				Write-Host "Drive could not be mapped! Removing automatic settings..." -ForegroundColor Red
          				sleep -seconds 5
          				$driveLetter=$null
          				$serverPath=$null
          				$mapUser=$null
          				$mapPassword=$null
          				Map-Drive $driveLetter $serverPath $mapUser $mapPassword}
          				
          			if ($counter -eq 3) {
          				Write-Host "Drive could not be mapped! Exiting map program." -ForegroundColor Red
          				sleep -seconds 5
          				return}
          				}
          		else{
          			Write-Host "Testing for proper mapping..."
          			sleep -seconds 4
          			Generate-Log-File-Line $logType "SUCCESS in mapping $serverPath to $driveLetter."
          			Write-Host "$serverPath was mapped successfully." -ForegroundColor Green
          			sleep -seconds 5}
          }
          

          Automated ISO and EXE Compiling Based On User Variables

          If a deployment network needed a quick PXE server to deploy certain images, a custom ISO can be built that includes injected NIC drivers AND injected drivers of all host machines, in addition to custom parameters for the network. This is significant as it allows one HAL independant image to be deployed without internet connection to various (and unknown) equipment rapidly across a network. Since this part isn’t particularly important to how my system works, I will display the tool’s full code here:

          @echo off&cls
          REM By David Maiolo
          
          set currentdir=%CD%
          set Scriptsandtools=%currentdir%\Support_Files\Scriptsandtools
          set driversdir=%currentdir%\Support_Files\Drivers
          set datapath=%currentdir%\Support_Files\Scriptsandtools\Support_Scripts\data
          notepad %datapath%\config\universal_settings.cmd
          call %datapath%\config\universal_settings.cmd
          
          color 1f
          echo -------------------------------------------------------------
          echo %product_title% %product_version% ISO Generator by %product_author%
          echo -------------------------------------------------------------
          echo.
          echo This utility is used to compile %product_title% %product_version%.
          echo.
          echo Prerequisites:
          echo.
          echo * RUN THIS PROGRAM AS AN ADMIN!
          echo * CD burning software to burn the ISO when we are done.
          echo * A blank CD or DVD.
          pause
          color 1f
          cls
          
          :STEP1
          
          cd %currentdir%\Support_Files
          cls
          echo ==================================================================
          echo Step 1: Set up a Windows PE build environment
          echo ==================================================================
          REM ---------------------------------------------
          echo.
          rd %install_dir%
          set install_dir=c:\imagedeployment_DVD_%product_version%
          echo The installation directory is:
          echo.
          echo %install_dir%
          echo.
          set askinstall_dir=n
          set /p askinstall_dir=Would you like to change this install dir for some reason?(y/n)
          if %askinstall_dir%==y (goto updateinstall_dir) else goto skipinstall_dir
          
          :updateinstall_dir
          set /p install_dir="Enter new install path. Do not use spaces ('c:\david_is_cool'):"
          
          :skipinstall_dir
          rd /s /q %install_dir%
          echo Run a script...
          call copype.cmd x86 %install_dir%
          
          echo Copy the base image into the sources folder and rename the file to Boot.wim...
          copy %install_dir%\winpe.wim %install_dir%\ISO\sources\boot.wim
          
          :STEP2
          cls
          echo ==================================================================
          echo Step 2: Add boot support
          echo ==================================================================
          REM --------------------------
          
          echo Apply the image to the \mount directory by using the DISM tool...
          Dism /Mount-Wim /Wimfile:%install_dir%\ISO\sources\boot.wim /index:1 /MountDir:%install_dir%\mount
          
          echo Add the appropriate boot support files and directory...
          copy %install_dir%\ISO\bootmgr %install_dir%\mount
          mkdir %install_dir%\mount\boot
          xcopy /cherky  %install_dir%\ISO\boot %install_dir%\mount\boot\
          
          :STEP3
          cls
          echo ==================================================================
          echo Step 3: Copy custom tools and scripts
          echo ==================================================================
          REM ---------------------------
          
          xcopy /s /e %Scriptsandtools% %install_dir%\mount
          rename %install_dir%\mount\autorun.txt autorun.inf
          copy /y %install_dir%\mount\autorun.inf %install_dir%\ISO
          copy /y %Scriptsandtools%\Support_Scripts\Generate_Key.cmd %install_dir%\ISO
          copy /y %Scriptsandtools%\Support_Scripts\Restore_Key.cmd %install_dir%\ISO
          copy /y %Scriptsandtools%\Support_Scripts\Mount_wim.cmd %install_dir%\ISO
          copy /y %Scriptsandtools%\Support_Scripts\1_prepare_for_capture.cmd %install_dir%\ISO
          copy /y %Scriptsandtools%\Support_Scripts\tools\startnet.cmd %install_dir%\mount\Windows\System32
          copy /y %Scriptsandtools%\Support_Scripts\tools\winpe.bmp %install_dir%\mount\Windows\System32
          copy /y %Scriptsandtools%\Support_Scripts\tools\winpe.jpg %install_dir%\mount\Windows\System32
          copy /y %Scriptsandtools%\Support_Scripts\tools\oledlg.dll %install_dir%\mount\Windows\System32
          copy /y %Scriptsandtools%\unattend.xml %install_dir%\ISO
          md %install_dir%\ISO\CreateDVD
          REM echo Adding Powershell..
          REM Dism /Add-Package /Image:"%install_dir%\mount" /PackagePath:%currentdir%\Support_Files\x86\WinPE-WMI.cab
          REM Dism /Add-Package /Image:"%install_dir%\mount" /PackagePath:%currentdir%\Support_Files\x86\WinPE-WMI_en-us.cab
          
          REM Dism /Add-Package /Image:"%install_dir%\mount" /PackagePath:%currentdir%\Support_Files\x86\WinPE-NetFx4.cab
          REM Dism /Add-Package /Image:"%install_dir%\mount" /PackagePath:%currentdir%\Support_Files\x86\WinPE-NetFx4_en-us.cab
          
          REM Dism /Add-Package /Image:"%install_dir%\mount" /PackagePath:%currentdir%\Support_Files\x86\WinPE-Scripting.cab
          REM Dism /Add-Package /Image:"%install_dir%\mount" /PackagePath:%currentdir%\Support_Files\x86\WinPE-Scripting_en-us.cab
          
          REM Dism /Add-Package /Image:"%install_dir%\mount" /PackagePath:%currentdir%\Support_Files\x86\WinPE-PowerShell3.cab
          REM Dism /Add-Package /Image:"%install_dir%\mount" /PackagePath:%currentdir%\Support_Files\x86\WinPE-PowerShell3_en-us.cab
          
          pause
          REM echo Creating Deployment DVD Staging Files...
          REM echo xcopy /s /e %currentdir% %install_dir%\ISO\CreateDVD
          REM xcopy /s /e %currentdir% %install_dir%\ISO\CreateDVD
          
          REM Add Drivers
          echo Adding Drivers from %driversdir%...
          Dism /Image:%install_dir%\mount /Add-Driver /Driver:%driversdir% /Recurse
          
          :STEP4
          cls
          echo ==================================================================
          echo Step 4: Configure BCD store: %install_dir%\mount\boot\BCD
          echo ==================================================================
          REM ---------------------------
          
          Del %install_dir%\mount\boot\BCD
          Bcdedit /createstore %install_dir%\mount\boot\BCD
          Bcdedit /store %install_dir%\mount\boot\BCD -create {bootmgr} /d "Boot Manager"
          Bcdedit /store %install_dir%\mount\boot\BCD -set {bootmgr} device boot
          echo Generating GUID...
          Bcdedit /store %install_dir%\mount\boot\BCD -create /d "WINPE" -application osloader
          set /p guid_variable="Enter GUID from output above (including '{' and '}':"
          
          Bcdedit /store %install_dir%\mount\boot\BCD -set %guid_variable% osdevice boot
          Bcdedit /store %install_dir%\mount\boot\BCD -set %guid_variable% device boot
          Bcdedit /store %install_dir%\mount\boot\BCD -set %guid_variable% path \windows\system32\winload.exe
          Bcdedit /store %install_dir%\mount\boot\BCD -set %guid_variable% systemroot \windows
          Bcdedit /store %install_dir%\mount\boot\BCD -set %guid_variable% winpe yes
          Bcdedit /store %install_dir%\mount\boot\BCD -displayorder %guid_variable% -addlast
          
          :STEP5
          cls
          echo ==================================================================
          echo Step 5: Commit Changes to %install_dir%\mount
          echo ==================================================================
          REM --------------------------
          Dism /Unmount-Wim /MountDir:%install_dir%\mount /Commit
          
          :STEP6
          cls
          echo ==================================================================
          echo Step 6: Create a bootable CD or DVD to %install_dir%\winpex86.iso
          echo ==================================================================
          REM --------------------------
          oscdimg -n -b%install_dir%\etfsboot.com %install_dir%\ISO %install_dir%\winpe_x86.iso
          REM Oscdimg -n -m -o -b%install_dir%\Etfsboot.com %install_dir%\ISO %install_dir%\winpe_x86.iso
          move %install_dir%\winpe_x86.iso %USERPROFILE%\Desktop\deployment_DVD_%product_version%.iso
          cls
          color 2f
          echo -----------------------------------------------------
          echo   %product_title% %product_version% Boot DVD creation Complete!
          echo -----------------------------------------------------
          echo.
          echo You can find your ISO file on your desktop.
          REM Explorer /select,%USERPROFILE%\Desktop\winpe_x86.iso
          pause
          echo Removing Temp files...
          rd /s /q %install_dir%
          color 07
          

          Automated ISO and EXE Compiling Based On User Variables

          NID Network Diagram

          Leave a Comment

          Your email address will not be published.