6/05/2009

Certificates for internet-based site systems in SCCM

Internet-based site systems in SCCM needs certifcates which has server authentication purpose e.g. Webserver Certificate. Important for this certificates is the FQDN name of the Server (or the defined DNS Alias) in either the certificate subject name field or the subject alternative name (SAN) field.
For Example: MYSCCM01.MYDOMAIN.LOCAL or SCCM.MYDOMAIN.COM

BUT!!! It's getting difficult if you want to use one certificate for Intranet and Internet usage. In this case both FQDN names must be included in certificate, but only one certificate subject name can be configured. In normal case also a Windows PKI issues only certificates with one SAN name, but this can be changed!

Execute the following command to extend the CA with the SAN2 extension, so that certificated getting issued with this fields:

certutil.exe -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTNAME2

After this stop and start the CA service

net stop certsvc && net start certsvc

Now you can issue certificates with more that one SAN name
To requst the certificate with more SAN names goto to your computer certificates mmc, request a new cetificate, choose your server authentication template and go to the properties page by clicking the details arrow.
Under alternative name select type 'DNS' and type in you FQDN names.

6/03/2009

Assign Windows PE Boot Image to Client

Windows Deployment Service (WDS) delivers a command line tool named wdsutil.exe, which can be used to prestage computers into Active Directory. I was personally intersted to get a Windows PE Boot Image automatically get choosen from a Client during Windows Boot Manager.
One purpose is for example if there are different Windows PE images for different processor architecture (x86, x64).
The parameter /BootImagePath defines the boot image which will be started by the client after the countdown

Example x86
WDSUTIL /Add-Device /Device:ComputerName /ID:MACAddress /ReferralServer:WDSServerName /BootProgram:boot\x86\pxeboot.com /BootImagePath:boot\x86\images\bootx86.wim

Example x64
WDSUTIL /Add-Device /Device:ComputerName /ID:MACAddress /ReferralServer:WDSServerName /BootProgram:boot\x64\pxeboot.com /BootImagePath:boot\x64\images\bootx64.wim

After executing the command, there's created a computer account in Active Directory which stores the configured options. Once a Client is booting from network now, it gets all information needed to choose the assigned boot image.
Note: Scripting the "WDSUTIL /Add-Device" command is nice for creating mutiple prestaged computer objects very comfortable


Further you can configure your WDS Server to only answer to known clients which delivers more control about the deployment.

3/06/2009

SQL SCCM Query to return Advertisements, Programs and Main Users of all Computers

This SCCM SQL Query return each Computer, it's Advertisements & Programs and the Main User

SELECT v_Advertisement.AdvertisementName, v_Advertisement.ProgramName,Netbios_Name0 as Computername,v_GS_SYSTEM_CONSOLE_USER.SystemConsoleUser0 as MainUsername
FROM
(SELECT ResourceID, MAX(TotalUserConsoleMinutes0) as Anmeldezeit
FROM v_GS_SYSTEM_CONSOLE_USER
GROUP BY ResourceID) AS Table1,v_GS_SYSTEM_CONSOLE_USER, v_R_System_Valid, v_ClientAdvertisementStatus, v_Advertisement WHERE Table1.ResourceID = v_GS_SYSTEM_CONSOLE_USER.ResourceID
AND Table1.Anmeldezeit = v_GS_SYSTEM_CONSOLE_USER.TotalUserConsoleMinutes0
AND Table1.ResourceID = v_R_System_Valid.ResourceID
AND Table1.ResourceID = v_ClientAdvertisementStatus.ResourceID
AND v_ClientAdvertisementStatus.AdvertisementID = v_Advertisement.AdvertisementID

1/28/2009

vbScript to validate SMS/SCCM Sourcepaths

This Script will check the Sourcepath for each package in SMS or SCCM if it is valid.

Siteserver = InputBox("Please enter the name of the SMS/SCCM Site Server")
Sitecode = InputBox("Please enter the Site Code of the SMS/SCCM Site")

Dim objFSO: Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim objFile : Set objFile = objFSO.CreateTextFile("ValidatePkgSourcePath.log")
Dim objSWbemLocator : Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Dim objSWbemServices : Set objSWbemServices = objSWbemLocator.ConnectServer (Siteserver, "root\sms\site_" + Sitecode)

Set colPackages=objSWbemServices.ExecQuery("SELECT * FROM SMS_Package")

For Each objPackage In colPackages
strPackageName = objPackage.Manufacturer &" " &objPackage.Name &" " &objPackage.Version &" " &objPackage.Language
If objPackage.PkgSourcepath = "" Then
objFile.WriteLine strPackageName &" - Sourcepath is empty"
End If
If Not objFSO.FolderExists(objPackage.PkgSourcepath) Then
objFile.WriteLine strPackageName &" - Sourcepath is not valid (" &objPackage.PkgSourcepath &")"
End If
Next
WScript.Echo "Finished"

9/04/2008

Retrieving "exit strings" from vbScript

Retrieving exit codes from vbScript is not very tricky, but there's no method to retrieve "exit strings" from a script.
Below there's listed a little workaround to keep strings in "computers mind" after a script finished without using tempfiles, registry keys or environment variables as data store.

Step by Step:

  1. ShowResult.vbs calls the script AskUser.vbs

  2. AskUser.vbs captures somes user input

  3. AskUser.vbs writes the user input into the windows clipboard

  4. AskUser.vbs ends

  5. ShowResults.vbs queries the clipboard for the written text

  6. ShowResults.vbs shows the result



ShowResult.vbs

Dim objShell : set objShell = CreateObject("Wscript.Shell")
Dim objIE :Set objIE = CreateObject("InternetExplorer.Application")

objShell.Run "\AskUser.vbs",1,True

objIE.Navigate("about:blank")
WScript.echo objIE.document.parentwindow.clipboardData.GetData("text")


AskUser.vbs

Dim objIE : Set objIE = CreateObject("InternetExplorer.Application")

If Msgbox("Please press YES or NO", vbYesNo) = vbYes Then
YourText = "YES was pressed"
Else
YourText = "NO was pressed"
End If

'Write to clipboard
objIE.Navigate("about:blank")
objIE.document.parentwindow.clipboardData.SetData "text", YourText

9/03/2008

vbScript to automatically changing a specific DNS Server on all Servers

The following vbScript replaces a specific DNS Server IP with another one, independed if the IP is the Primary or Secondary DNS Server.

Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim objShell : Set objShell = CreateObject("Wscript.Shell")
Dim objFile : Set objFile = objFSO.OpenTextFile("c:\computers.txt")
Dim strOldIP : strOldIP = "1.1.1.1"
dim strNewIP : strNewIP = "2.2.2.2"
Dim arrDNSServer(2)
dim i : i = 0

Do While Not objFile.AtEndOfStream
currentserver = objFile.ReadLine
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & currentserver & "\root\cimv2")
Set colNicConfigs = objWMIService.ExecQuery ("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")

For Each objNicConfig In colNicConfigs
If Not IsNull(objNicConfig.DNSServerSearchOrder) Then
For Each strDNSServer In objNicConfig.DNSServerSearchOrder
arrDNSServer(i) = strDNSServer
i=i+1
Next
End If
Next

If arrDNSServer(0) = strOldIP Then
'Changing the primary dns server
objShell.Run "netsh -r " ¤tserver &" interface ip set dnsserver " &chr(34) &"local area connection" &Chr(34) &" static " &strNewIP &" primary",1,True
objShell.Run "netsh -r " ¤tserver &" interface ip delete dnsserver " &chr(34) &"local area connection" &Chr(34) &" " &arrDNSServer(1),1,True
objShell.Run "netsh -r " ¤tserver &" interface ip add dns " &chr(34) &"local area connection" &Chr(34) &" " &arrDNSServer(1) &" index=2",1,True
ElseIf arrDNSServer(1) = strOldIP Then
'Changing the secondary DNS Server
objShell.Run "netsh -r " ¤tserver &" interface ip delete dnsserver " &chr(34) &"local area connection" &Chr(34) &" " &arrDNSServer(0),1,True
objShell.Run "netsh -r " ¤tserver &" interface ip set dnsserver " &chr(34) &"local area connection" &Chr(34) &" static " &arrDNSServer(0) &" primary",1,True
objShell.Run "netsh -r " ¤tserver &" interface ip add dns " &chr(34) &"local area connection" &Chr(34) &" " &strNewIP &" index=2",1,True
End If
i = 0
Loop

9/02/2008

Get User's last successful and failed logon

The following VBScript will show the last successful and the last failed logon of the current user. Depending of the OS Version the event id's from eventvwr has to be customized.


Dim objNetwork : Set objNetwork = CreateObject("WScript.Network")
strComputer = "."
Dim EventTime, strUsername
strLogonSuccess = "528"
strLogonError = "529"
Set objWMIService = GetObject("winmgmts:" & "{(Security)}!\\" & strComputer & "\root\cimv2")

'Determine the last successful logon process
Set colLoggedEvents = objWMIService.ExecQuery ("Select * from Win32_NTLogEvent Where Logfile = 'Security' and EventCode = '" &strLogonSuccess &"'")
For Each objEvent in colLoggedEvents
If Not IsNull(objEvent.User) And objEvent.User = objNetwork.UserDomain &"\" &objNetwork.UserName Then
If cint(objEvent.Eventcode) = cint(strLogonSuccess) Then
Call ConvertTime(objEvent.TimeWritten)
Wscript.Echo "The last successful Logon from " &objEvent.User &" was at " &EventTime
Exit For
End If
End If
Next

'Determine the last failed logon process
Set colLoggedEvents = objWMIService.ExecQuery ("Select * from Win32_NTLogEvent Where Logfile = 'Security' and EventCode = '" &strLogonError &"'")
For Each objEvent in colLoggedEvents
'Convert username out of the eventvwr message
Call GetUsername(objEvent.Message)

'Check if username from event matches local logged in user
If lcase(cstr(strUsername)) = lcase(cstr(objNetwork.UserName)) Then
If cint(objEvent.Eventcode) = cint(strLogonError) Then
Call ConvertTime(objEvent.TimeWritten)
Wscript.Echo "The last failed Logon from " &strUsername &" was at " &EventTime
Exit For
End If
End If
Next

Function ConvertTime(datetime)
EventTime = Mid(datetime, 5, 2) & "/" & Mid(datetime, 7, 2) & "/" & _
Mid(datetime, 1, 4) & " " & Mid(datetime, 9, 2) & ":" & _
Mid(datetime, 11, 2) & "." & Mid(datetime, 13, 2)
End Function

Function GetUsername(strMessage)
strStart = InStr(strMessage,"User Name:") + 10
strEnd = InStr(strMessage,"Domain:")
strLen = strEnd - strStart

strUsername = Replace(Replace(Replace(Replace(Mid(strMessage,strStart,strLen)," ",""),vbTab, ""),VbCrLf,""), vbNewLine,"")
End Function