Home
WOL TOOL (C#)
- Written by Kasia Persson
- Hits: 7905
WOL TOOL (C#)
Scenario
We are supporting about 40 schools with their it systems, all computers are joined to the domain, we are running SCCM environment which we use to deploy software and operating systems to pc’s, inventory, patching etc.
In our Active Directory forest every school has its own OU.
We have one standalone SCCM server (Primary Site), and one distribution point located in every school.
I would make a tool for our support persons, which let them start, logoff, restart and shutdown pc’s in all class rooms.
It was important to have opportunities to take action in every room separately.
We don’t have VLAN’s for every room, so it is impossible to make the tool based on ip addresses. Our support persons don’t like the idea of finding mac addresses of all pc’s and save it to the txt file. A Mac address is necessary to run magic packages – Wake On Lan(WOL).
I have found out that all computer names are stored in AD and mac-address with names in sccm database. I just had to figure how to create and match two lists - one from AD with names and one from sccm database with mac addresses and computer names.
I asked our supporters to add the description for each computer in AD with the name of the room where the computer is placed.
Based on it I could create tree view with pc name and room name.
Basically, the program is based on windows scheduled task - it is a little GUI with an opportunity of setting scheduled task with triggers for each school and classroom.
Tool overview
On the main page is the list of the name of tasks. Tasks can be enabled, disabled, or we can set status to expired.
Program is writing the tasks to the Task Scheduler
But the end user doesn’t need to think about it….
I made three buttons, one to edit task, one to add the new task, and finally one to delete task.
When we click the green button, we will be redirected to a new form where we can specify all task information like name description, task type…
General
-
There are three tabs - we need to add information to all of them.
-
We can enable or disable task (sometimes useful in exam period or holidays)
-
We need to specify the action
-
We can execute task once immediately (if we would like to restart all computers in classroom before the new class is coming)
Computers
When we move to “Computers” tab, we get a list of computers which will be affected by the action, if we have added them to the list.
-
We can add or remove computers, if we choose to add the new computers, we will be redirected to the new form with tree view of the computers (it is mirroring our AD description for computer. Tree view list description text up to dash (-) if we write in computer description fx “Lokale 8 – green room” it will be shown as “Lokal 8” thanks to the user who has the opportunity to add some extra information which is not necessary to display on the list)
-
In the textbox we have to choose the name of the school OU and reload the list.
Triggers
-
In triggers tab, we have to schedule time and date of task execution. Optionally, we can set expiry date.
Specification
Program needs two views in SCCM SQL database, one user with permission to Database and AD User with permissions to Computers.
SQL Views
Program is running SQL query where it picks up data from three views, two of which we create ourselves (ODKinvOSBIOSRAM and ODKinvNetCard).
In my query I just select all computers where name is starting with school initials and “PC”:
AND PCID LIKE @schoolname+'PC%'
You can just remove it then you get all computers, I don’t want to run it on the laptops since we have different naming standards for laptops and PC.
To create Views, open SQL Management Studio and run Query (you need to change value - CM_CM1 so it matches your site-database name ) :
-
ODKinvOSBIOSRAM
USE [CM_CM1]
GO
/****** Object: View [dbo].[ODKinvOSBIOSRAM] Script Date: 13-01-2017 10:54:00 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[ODKinvOSBIOSRAM]
AS
SELECT dbo.v_R_System.ResourceID AS SMSID, dbo.v_R_System.Name0 AS PCID, dbo.Computer_System_DATA.Model00 AS Model,
dbo.PC_BIOS_DATA.SerialNumber00 AS BiosSN, dbo.System_Enclosure_DATA.ChassisTypes00 AS ChassisType, dbo.Operating_System_DATA.Caption00 AS OSYS,
dbo.Operating_System_DATA.CSDVersion00 AS OSSP, dbo.Operating_System_DATA.Version00 AS OSver, dbo.v_R_System.Active0 AS SMSstatus,
dbo.v_R_System.Creation_Date0 AS FirstContact, dbo.WorkstationStatus_DATA.LastHWScan AS LastContact,
dbo.v_R_System.User_Domain0 + '\' + dbo.v_R_System.User_Name0 AS PriUser, dbo.PC_Memory_DATA.TotalPhysicalMemory00 / 1024 AS RAM,
dbo.Computer_System_DATA.NumberOfProcessors00 AS CPUantal, dbo.Computer_System_DATA.UserName00 AS PriUser2, dbo.System_Enclosure_DATA.MachineID,
dbo.WorkstationStatus_DATA.MachineID AS Expr1, dbo.Computer_System_DATA.MachineID AS Expr2
FROM dbo.Operating_System_DATA FULL OUTER JOIN
dbo.PC_Memory_DATA FULL OUTER JOIN
dbo.WorkstationStatus_DATA FULL OUTER JOIN
dbo.System_Enclosure_DATA FULL OUTER JOIN
dbo.v_R_System ON dbo.System_Enclosure_DATA.MachineID = dbo.v_R_System.ResourceID ON
dbo.WorkstationStatus_DATA.MachineID = dbo.v_R_System.ResourceID FULL OUTER JOIN
dbo.PC_BIOS_DATA ON dbo.v_R_System.ResourceID = dbo.PC_BIOS_DATA.MachineID FULL OUTER JOIN
dbo.Computer_System_DATA ON dbo.v_R_System.ResourceID = dbo.Computer_System_DATA.MachineID ON
dbo.PC_Memory_DATA.MachineID = dbo.v_R_System.ResourceID ON dbo.Operating_System_DATA.MachineID = dbo.v_R_System.ResourceID
GO
-
ODKinvNetCard
USE [CM_CM1]
GO
/****** Object: View [dbo].[ODKinvNetCard] Script Date: 13-01-2017 10:55:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[ODKinvNetCard]
AS
SELECT dbo.Netcard_DATA.MachineID AS SMSid, dbo.Netcard_DATA.Description00 AS Netcard, dbo.Network_DATA.IPAddress00 AS IPadress,
dbo.Network_DATA.IPSubnet00 AS IPsubnet, dbo.Network_DATA.DefaultIPGateway00 AS IpGateway, dbo.Network_DATA.DHCPEnabled00 AS DHCP,
dbo.Netcard_DATA.MACAddress00 AS MAC
FROM dbo.Netcard_DATA INNER JOIN
dbo.Network_DATA ON dbo.Netcard_DATA.MachineID = dbo.Network_DATA.MachineID AND dbo.Netcard_DATA.DeviceID00 = dbo.Network_DATA.Index00
WHERE (dbo.Netcard_DATA.MachineID IN
(SELECT DISTINCT MachineID
FROM dbo.Netcard_DATA AS Netcard_DATA_2)) AND (dbo.Netcard_DATA.Description00 IN
(SELECT DISTINCT Description00
FROM dbo.Netcard_DATA AS Netcard_DATA_1
WHERE (Description00 NOT LIKE '%miniport%') AND (Description00 NOT LIKE '%direkte%') AND (Description00 NOT LIKE '%Eicon%') AND
(Description00 NOT LIKE '%direct%') AND (Description00 NOT LIKE '%Deterministic%') AND (Description00 NOT LIKE '%Wireless%') AND
(Description00 NOT LIKE '%asynkron%') AND (Description00 NOT LIKE '%async%') AND (Description00 NOT LIKE '%infra%') AND
(Description00 NOT LIKE '%TV/Video%'))) AND (dbo.Netcard_DATA.Description00 NOT LIKE '%cisco%') AND
(dbo.Netcard_DATA.Description00 NOT LIKE '%bluetooth%')
GROUP BY dbo.Netcard_DATA.MachineID, dbo.Netcard_DATA.Description00, dbo.Network_DATA.IPAddress00, dbo.Network_DATA.IPSubnet00,
dbo.Network_DATA.DefaultIPGateway00, dbo.Network_DATA.DHCPEnabled00, dbo.Netcard_DATA.MACAddress00
GO
-
ODKinvMAC
USE [CM_CM1]
GO
/****** Object: View [dbo].[ODKinvMAC] Script Date: 13-01-2017 10:53:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[ODKinvMAC]
AS
SELECT dbo.ODKinvOSBIOSRAM.PCID, dbo.ODKinvNetCard.Netcard, dbo.ODKinvNetCard.MAC, dbo.ODKinvOSBIOSRAM.SMSstatus
FROM dbo.ODKinvNetCard INNER JOIN
dbo.ODKinvOSBIOSRAM ON dbo.ODKinvNetCard.SMSid = dbo.ODKinvOSBIOSRAM.SMSID
WHERE (dbo.ODKinvOSBIOSRAM.SMSstatus = 1) AND (dbo.ODKinvNetCard.MAC IS NOT NULL)
GO
Settings
There is a settings file with important info, which must be specific to your environment.
-
Program is picking up all data such as credentials, name of database, OU from one file – Settings
-
Specify from which OU you want to get computers on tree view fx:
LDAP://OU=DESKTOPS,OU=COMPUTERS,OU={0},OU=Office,OU=City,DC=domain,DC=com
OU={0} – in our case it is a school name we write in GUI, in our AD structure every school has its own OU.
Source files:
Promt Computer Name and NetCard Settings during OSD TaskSequence in SCCM
- Written by Kasia and Jan
- Hits: 9656
Create PsScript (GUI set value to TSEnvVariables)
We have used and modified Nikolaj Andersens script (http://www.scconfigmgr.com/2013/10/02/prompt-for-computer-name-during-osd-with-powershell/)
Her is our version:
Here is modified Script:
<#
.NOTES
===========================================================================
Created with: SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.3.131
Created on: 02-01-2017 12:43
Created by: KASIA
Organization: XXX
Filename:
===========================================================================
.DESCRIPTION
A description of the file.
#>
Function Load-Form
{
$Form.Controls.Add($TBComputerName)
$Form.Controls.Add($GBComputerName)
$Form.Controls.Add($TBComputerIP)
$Form.Controls.Add($GBComputerIP)
$Form.Controls.Add($TBComputerGW)
$Form.Controls.Add($GBComputerGW)
$Form.Controls.Add($TBComputerDNS)
$Form.Controls.Add($GBComputerDNS)
$Form.Controls.Add($TBComputerDNS2)
$Form.Controls.Add($GBComputerDNS2)
$Form.Controls.Add($ButtonOK)
$Form.Add_Shown({ $Form.Activate() })
$TBComputerIP.add_TextChanged({
$ip2 = $TBComputerIP.text.split('.')
if($ip2.count -lt 4) {
$TBComputerGW.text = $TBComputerIP.text
} else {
$ip2[-1] = 1
$TBComputerGW.text = $ip2 -join '.'
}
})
[void]$Form.ShowDialog()
}
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$Global:ErrorProvider = New-Object System.Windows.Forms.ErrorProvider
$Form = New-Object System.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(285, 440)
$Form.MinimumSize = New-Object System.Drawing.Size(285, 440)
$Form.MaximumSize = New-Object System.Drawing.Size(285, 440)
$Form.StartPosition = "CenterScreen"
$Form.SizeGripStyle = "Hide"
$Form.Text = "Enter Computer Informations"
$Form.ControlBox = $false
$Form.TopMost = $true
$TBComputerName = New-Object System.Windows.Forms.TextBox
$TBComputerName.Location = New-Object System.Drawing.Size(25, 30)
$TBComputerName.Size = New-Object System.Drawing.Size(215, 50)
$TBComputerName.TabIndex = "1"
$GBComputerName = New-Object System.Windows.Forms.GroupBox
$GBComputerName.Location = New-Object System.Drawing.Size(20, 10)
$GBComputerName.Size = New-Object System.Drawing.Size(225, 50)
$GBComputerName.Text = "Computer name:"
$TBComputerIP = New-Object System.Windows.Forms.TextBox
$TBComputerIP.Location = New-Object System.Drawing.Size(25, 100)
$TBComputerIP.Size = New-Object System.Drawing.Size(215, 50)
$TBComputerIP.TabIndex = "1"
$GBComputerIP = New-Object System.Windows.Forms.GroupBox
$GBComputerIP.Location = New-Object System.Drawing.Size(20, 80)
$GBComputerIP.Size = New-Object System.Drawing.Size(225, 50)
$GBComputerIP.Text = "IP:"
$TBComputerGW = New-Object System.Windows.Forms.TextBox
$TBComputerGW.Location = New-Object System.Drawing.Size(25, 170)
$TBComputerGW.Size = New-Object System.Drawing.Size(215, 50)
$TBComputerGW.TabIndex = "1"
$GBComputerGW = New-Object System.Windows.Forms.GroupBox
$GBComputerGW.Location = New-Object System.Drawing.Size(20, 150)
$GBComputerGW.Size = New-Object System.Drawing.Size(225, 50)
$GBComputerGW.Text = "Gateway:"
$TBComputerDNS = New-Object System.Windows.Forms.TextBox
$TBComputerDNS.Location = New-Object System.Drawing.Size(25, 240)
$TBComputerDNS.Size = New-Object System.Drawing.Size(215, 50)
$TBComputerDNS.TabIndex = "1"
#$TBComputerDNS.text = "10.10.10.1"
$GBComputerDNS = New-Object System.Windows.Forms.GroupBox
$GBComputerDNS.Location = New-Object System.Drawing.Size(20, 220)
$GBComputerDNS.Size = New-Object System.Drawing.Size(225, 50)
$GBComputerDNS.Text = "DNS:"
$TBComputerDNS2 = New-Object System.Windows.Forms.TextBox
$TBComputerDNS2.Location = New-Object System.Drawing.Size(25, 310)
$TBComputerDNS2.Size = New-Object System.Drawing.Size(215, 50)
$TBComputerDNS2.TabIndex = "1"
#$TBComputerDNS2.text = "10.10.10.2"
$GBComputerDNS2 = New-Object System.Windows.Forms.GroupBox
$GBComputerDNS2.Location = New-Object System.Drawing.Size(20, 290)
$GBComputerDNS2.Size = New-Object System.Drawing.Size(225, 50)
$GBComputerDNS2.Text = "DNS:"
$ButtonOK = New-Object System.Windows.Forms.Button
$ButtonOK.Location = New-Object System.Drawing.Size(195, 360)
$ButtonOK.Size = New-Object System.Drawing.Size(50, 20)
$ButtonOK.Text = "OK"
$ButtonOK.TabIndex = "2"
$ButtonOK.Add_Click({
##Set-ComputerName##
$ErrorProvider.Clear()
if ($TBComputerName.Text.Length -eq 0)
{
$ErrorProvider.SetError($GBComputerName, "Please enter a computer name.")
return
}
elseif ($TBComputerName.Text.Length -gt 15)
{
$ErrorProvider.SetError($GBComputerName, "Computer name cannot be more than 15 characters.")
return
}
#Validation Rule for computer names.
elseif ($TBComputerName.Text -match "^[-_]|[^a-zA-Z0-9-_]")
{
$ErrorProvider.SetError($GBComputerName, "Computer name invalid, please correct the computer name.")
return
}
else
{
$OSDComputerName = $TBComputerName.Text.ToUpper()
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$TSEnv.Value("OSDComputerName") = "$($OSDComputerName)"
#$Form.Close()
}
##Set-OSDComputerIP##
if ($TBComputerIP.Text.Length -eq 0)
{
$ErrorProvider.SetError($GBComputerIP, "Please enter a computer IP.")
return
}
elseif ($TBComputerIP.Text.Length -gt 15)
{
$ErrorProvider.SetError($GBComputerIP, "Computer IP cannot be more than 15 characters.")
return
}
#Validation Rule for computer IP.
$ip = [regex]"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
if ($ip.IsMatch($TBComputerIP.text) -ne $true)
{
$ErrorProvider.SetError($GBComputerIP, "Computer IP invalid, please correct the computer IP.")
return
}
else
{
$OSDComputerIP = $TBComputerIP.Text
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$TSEnv.Value("OSDAdapter0IPAddressList") = "$($OSDComputerIP)"
$TSEnv.Value("OSDAdapter0SubnetMask") = "255.255.255.0"
$TSEnv.Value("OSDAdapter0EnableDHCP") = "False"
$TSEnv.Value("OSDAdapterCount") = "1"
#$Form.Close()
}
##Set-OSDComputerGW##
if ($TBComputerGW.Text.Length -eq 0)
{
$ErrorProvider.SetError($GBComputerGW, "Please enter a computer Gateway.")
return
}
elseif ($TBComputerGW.Text.Length -gt 15)
{
$ErrorProvider.SetError($GBComputerGW, "Computer Gateway cannot be more than 15 characters.")
return
}
#Validation Rule for computer GW.
$GWip = [regex]"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
if ($GWip.IsMatch($TBComputerGW.text) -ne $true)
{
$ErrorProvider.SetError($GBComputerGW, "Computer Gateway invalid, please correct the computer Gateway.")
return
}
else
{
$OSDComputerGW = $TBComputerGW.Text
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$TSEnv.Value("OSDAdapter0Gateways") = "$($OSDComputerGW)"
#$Form.Close()
}
##Set-OSDComputerDNS##
if ($TBComputerDNS.Text.Length -eq 0)
{
$ErrorProvider.SetError($GBComputerDNS, "Please enter a computer DNS.")
return
}
elseif ($TBComputerDNS.Text.Length -gt 15)
{
$ErrorProvider.SetError($GBComputerDNS, "Computer DNS cannot be more than 15 characters.")
return
}
elseif ($TBComputerDNS2.Text.Length -eq 0)
{
$ErrorProvider.SetError($GBComputerDNS2, "Please enter a computer DNS.")
return
}
elseif ($TBComputerDNS2.Text.Length -gt 15)
{
$ErrorProvider.SetError($GBComputerDNS2, "Computer DNS cannot be more than 15 characters.")
return
}
#Validation Rule for computer DNS.
$DNSip = [regex]"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
if ($DNSip.IsMatch($TBComputerDNS.text) -ne $true)
{
$ErrorProvider.SetError($GBComputerDNS, "Computer DNS invalid, please correct the computer DNS.")
return
}
$DNS2ip = [regex]"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
$DNS2ip.IsMatch($TBComputerDNS2.text)
if ($DNS2ip.IsMatch($TBComputerDNS2.text) -ne $true)
{
$ErrorProvider.SetError($GBComputerDNS2, "Computer DNS invalid, please correct the computer DNS.")
return
}
else
{
$OSDComputerDNS = $TBComputerDNS.Text
$OSDComputerDNS2 = $TBComputerDNS2.Text
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$TSEnv.Value("OSDAdapter0DNSServerList") = "$($OSDComputerDNS),$($OSDComputerDNS2)"
}
$Form.Close()
})
$Form.KeyPreview = $True
$Form.Add_KeyDown({
if ($_.KeyCode -eq "Enter")
{ ##Set-ComputerName##
$ErrorProvider.Clear()
if ($TBComputerName.Text.Length -eq 0)
{
$ErrorProvider.SetError($GBComputerName, "Please enter a computer name.")
return
}
elseif ($TBComputerName.Text.Length -gt 15)
{
$ErrorProvider.SetError($GBComputerName, "Computer name cannot be more than 15 characters.")
return
}
#Validation Rule for computer names.
elseif ($TBComputerName.Text -match "^[-_]|[^a-zA-Z0-9-_]")
{
$ErrorProvider.SetError($GBComputerName, "Computer name invalid, please correct the computer name.")
return
}
else
{
$OSDComputerName = $TBComputerName.Text.ToUpper()
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$TSEnv.Value("OSDComputerName") = "$($OSDComputerName)"
#$Form.Close()
}
##Set-OSDComputerIP##
if ($TBComputerIP.Text.Length -eq 0)
{
$ErrorProvider.SetError($GBComputerIP, "Please enter a computer IP.")
return
}
elseif ($TBComputerIP.Text.Length -gt 15)
{
$ErrorProvider.SetError($GBComputerIP, "Computer IP cannot be more than 15 characters.")
return
}
#Validation Rule for computer IP.
$ip = [regex]"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
if ($ip.IsMatch($TBComputerIP.text) -ne $true)
{
$ErrorProvider.SetError($GBComputerIP, "Computer IP invalid, please correct the computer IP.")
return
}
else
{
$OSDComputerIP = $TBComputerIP.Text
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$TSEnv.Value("OSDAdapter0IPAddressList") = "$($OSDComputerIP)"
$TSEnv.Value("OSDAdapter0SubnetMask") = "255.255.255.0"
$TSEnv.Value("OSDAdapter0EnableDHCP") = "False"
$TSEnv.Value("OSDAdapterCount") = "1"
#$Form.Close()
}
##Set-OSDComputerGW##
if ($TBComputerGW.Text.Length -eq 0)
{
$ErrorProvider.SetError($GBComputerGW, "Please enter a computer Gateway.")
return
}
elseif ($TBComputerGW.Text.Length -gt 15)
{
$ErrorProvider.SetError($GBComputerGW, "Computer Gateway cannot be more than 15 characters.")
return
}
#Validation Rule for computer GW.
$GWip = [regex]"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
if ($GWip.IsMatch($TBComputerGW.text) -ne $true)
{
$ErrorProvider.SetError($GBComputerGW, "Computer Gateway invalid, please correct the computer Gateway.")
return
}
else
{
$OSDComputerGW = $TBComputerGW.Text
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$TSEnv.Value("OSDAdapter0Gateways") = "$($OSDComputerGW)"
#$Form.Close()
}
##Set-OSDComputerDNS##
if ($TBComputerDNS.Text.Length -eq 0)
{
$ErrorProvider.SetError($GBComputerDNS, "Please enter a computer DNS.")
return
}
elseif ($TBComputerDNS.Text.Length -gt 15)
{
$ErrorProvider.SetError($GBComputerDNS, "Computer DNS cannot be more than 15 characters.")
return
}
elseif ($TBComputerDNS2.Text.Length -eq 0)
{
$ErrorProvider.SetError($GBComputerDNS2, "Please enter a computer DNS.")
return
}
elseif ($TBComputerDNS2.Text.Length -gt 15)
{
$ErrorProvider.SetError($GBComputerDNS2, "Computer DNS cannot be more than 15 characters.")
return
}
#Validation Rule for computer DNS.
$DNSip = [regex]"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
if ($DNSip.IsMatch($TBComputerDNS.text) -ne $true)
{
$ErrorProvider.SetError($GBComputerDNS, "Computer DNS invalid, please correct the computer DNS.")
return
}
$DNS2ip = [regex]"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
$DNS2ip.IsMatch($TBComputerDNS2.text)
if ($DNS2ip.IsMatch($TBComputerDNS2.text) -ne $true)
{
$ErrorProvider.SetError($GBComputerDNS2, "Computer DNS invalid, please correct the computer DNS.")
return
}
else
{
$OSDComputerDNS = $TBComputerDNS.Text
$OSDComputerDNS2 = $TBComputerDNS2.Text
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$TSEnv.Value("OSDAdapter0DNSServerList") = "$($OSDComputerDNS),$($OSDComputerDNS2)"
}
$Form.Close() }
})
Load-Form
Update your boot image to support PowerShell
If you havn’t already updated your boot images with PowerShell support, follow these instructions.
1. Right-click on your boot image and select Properties.
2. Select the Optional Components tab.
3. Click on the yellow star and select the following components:
-
Microsoft .NET (WinPE-NetFx4)
-
Windows PowerShell (WinPE-PowerShell3)
Note! In ConfigMgr 2012 R2 the names of the optional components differ a bit. Add the following:
-
Microsoft .NET (WinPE-NetFx)
-
Windows PowerShell (WinPE-PowerShell)
4. Click OK and then OK again. Let the wizard update your DP’s
Implement the script in a Task Sequence
1. Edit the Task Sequence that you wish to add this functionality to.
2. Add a Run Command Line step in between the Partition Disk and Apply Operating System steps.
3. Rename the Run Command Line step to Prompt for ComputerName.
4. Edit the Command Line so that it looks like this:
-
ServiceUI.exe -process:TSProgressUI.exe %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File Set-OSDComputerNamePrompt.ps1
5. Put a check mark in the Package box, click Browse and select your newly created package (OSDComputerName).
Flush Variables.dat file
We have referred to Johan Blog:
Make ZTIFlushVariables.wsf script and save it in %SCRIPTROOT%
<job id="ZTIFlushVariables">
<script language="VBScript" src="ZTIUtility.vbs"/>
<script language="VBScript">
' Flush variables set via PowerShell to Variables.dat (workaround for bug in MDT 2013 Update 2)
Dim oTSEnv
Set oTSEnv = CreateObject("Microsoft.SMS.TSEnvironment")
Dim oVar
For Each oVar In oTSEnv.GetVariables
' Only worry about variables that have a value
If oEnvironment.Item(oVar) <> "" Then
' Log variable before flush
oLogging.CreateEntry "---------------------------------------------------------------------------", LogTypeInfo
oLogging.CreateEntry "Before Flush: " & oVar & " variable from Variables.dat: " & oEnvironment.GetDat(oVar), LogTypeInfo
' Flush the variable
oEnvironment.Item(oVar) = oEnvironment.Item(oVar)
' Log variable after flush
oLogging.CreateEntry "After Flush: " & oVar & " variable from Variables.dat: " & oEnvironment.GetDat(oVar), LogTypeInfo
End if
Next
</script>
</job>
Call a VBscript that resets the value to whatever value your PowerShell script set, then just run that script after your PowerShell script.
Add OSDAdapterCount value in Task Sequence
VOILA! DONE! J