Using SQL to list the Site Servers, Roles and Boundaries of the SCCM Hierarchy

Today I was trying to gather a list of all of our site servers and roles.  I then wanted to find out what site servers were protected.  The built in reports the SCCM provides did not have all this information.  That’s OK….as long as we know SQL!

-- Create Table #One

-- (

-- SiteCode varchar(256)

-- , ServerName varchar (256)

-- , RoleName varchar (256)

-- )

--

-- Insert into #One (Sitecode,servername,rolename)

--

create view v_SCCM_ServerInfrastructure as -- decided to create view instead of temp table

SELECT sys.SiteCode, sys.ServerName,

    case when sys.RoleName='SMS Distribution Point' 

        then case when dp.IsPeerDP=1 then 'SMS Branch Distribution Point'

            else 'SMS Standard Distribution Point' end

    else sys.RoleName end as 'RoleName'

FROM v_SystemResourceList as sys

left join v_DistributionPointInfo as dp

on sys.NALPath = dp.NALPath

-- Order by sys.SiteCode, sys.ServerName, RoleName  -- need to comment out for the Create View statement

--

-- Create Table #Two

-- (

-- ServerName varchar (256)

-- , SiteCode varchar(256)

-- , value varchar (256)

-- , displayname varchar (256)

-- , rolename varchar (256)

-- )

--

-- Insert into #Two (servername,sitecode,value,displayname, rolename)

--

create view v_SCCM_DistributionPoints as -- decided to create view instead of temp table

select dp.ServerName

,bi.SiteCode

,bi.value

,bi.displayname

,case when dp.IsPeerDP=1 then 'SMS Branch Distribution Point'

            else 'SMS Standard Distribution Point' end as 'RoleName'

from v_DistributionPointInfo as dp

left join ProtectedSiteSystem_ARR ps

on ps.servername = dp.servername

left join v_BoundaryInfo bi

on ps.boundaryID = bi.boundaryID

-- order by ps.servername -- need to comment out for the Create View statement

--

-- select * from #one

-- select * from #two

--

-- select a.SiteCode, a.Servername, a.RoleName, b.value as 'Boundary', b.displayname as 'Boundary_Displayname'

-- from #one a

-- left join #two b

-- on a.rolename = b.rolename and a.servername = b.servername

-- order by a.SiteCode, a.Rolename

--

create view v_SCCM_Server_Infrastructure_Boundaries as

select a.SiteCode, a.Servername, a.RoleName, b.value as 'Boundary', b.displayname as 'Boundary_Displayname'

from v_SCCM_ServerInfrastructure a

left join v_SCCM_DistributionPoints b

on a.rolename = b.rolename and a.servername = b.servername

--

select * from v_SCCM_Server_Infrastructure_Boundaries

order by SiteCode, Rolename

Using SCCM to get Local User Group Membership and Local User Password Expiration

Recently the server team asked me if SCCM could gather Local Group Membership and Local User Password Expiration.

After a bit of Googling, I found an article by Sherry Kissenger (isn’t she just the best!).  The article describes how to get Local Group Membership.  Using the knowledge that she provided, I was able to extend her script to gather Local User Password Expiration.

Here is Sherry’s original post.  You will want to follow all of her directions since I won’t be reposting them.  I can state that her instructions were very easy to follow and everything worked great!  http://myitforum.com/cs2/blogs/skissinger/archive/2010/04/25/report-on-all-members-of-all-local-groups.aspx

Here is the modified VBScript that I used to gather both Local Group Membership and Local User Password Expiration

on error resume next
'Steps
'enumerate from win32_group where localaccount=1
'Read in the members of each local group returned
'Add the returned information to a custom WMI namespace
'sms-def.mof to pull that back.
Set fso = CreateObject("Scripting.FileSystemObject") 
Set nwo = CreateObject("Wscript.Network") 
Set sho = CreateObject("Wscript.Shell") 
TempFolder = sho.ExpandEnvironmentStrings("%temp%")
strWindir = sho.ExpandEnvironmentStrings("%windir%")
strComputer = nwo.ComputerName
Dim wbemCimtypeSint16 
Dim wbemCimtypeSint32 
Dim wbemCimtypeReal32 
Dim wbemCimtypeReal64 
Dim wbemCimtypeString 
Dim wbemCimtypeBoolean 
Dim wbemCimtypeObject 
Dim wbemCimtypeSint8 
Dim wbemCimtypeUint8 
Dim wbemCimtypeUint16 
Dim wbemCimtypeUint32 
Dim wbemCimtypeSint64 
Dim wbemCimtypeUint64 
Dim wbemCimtypeDateTime 
Dim wbemCimtypeReference 
Dim wbemCimtypeChar16 

wbemCimtypeSint16 = 2 
wbemCimtypeSint32 = 3 
wbemCimtypeReal32 = 4 
wbemCimtypeReal64 = 5 
wbemCimtypeString = 8 
wbemCimtypeBoolean = 11 
wbemCimtypeObject = 13 
wbemCimtypeSint8 = 16 
wbemCimtypeUint8 = 17 
wbemCimtypeUint16 = 18 
wbemCimtypeUint32 = 19 
wbemCimtypeSint64 = 20 
wbemCimtypeUint64 = 21 
wbemCimtypeDateTime = 101 
wbemCimtypeReference = 102 
wbemCimtypeChar16 = 103 
' Remove classes 
Set oLocation = CreateObject("WbemScripting.SWbemLocator") 
'===================
'If this is a Domain Controller, bail!
'===================
Set oWMI = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colComputer = oWMI.ExecQuery _
("Select DomainRole from Win32_ComputerSystem")
For Each oComputer in colComputer
 if (oComputer.DomainRole = 4 or oComputer.DomainRole = 5) then
   wscript.echo "DomainController, So I'm quitting!"
   'wscript.quit
 Else
'==================
'If it is NOT a domain controller, then continue gathering info 
'and stuff it into WMI for later easy retrieval
'==================

Set oServices = oLocation.ConnectServer(,"root\cimv2") 
set oNewObject = oServices.Get("CM_LocalGroupMembers") 
oNewObject.Delete_ 
'==================
'Get the local Group Names
'==================
Dim iGroups(300)
i=0
Set objWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colGroup = objWMIService.ExecQuery("select * from win32_group where localaccount=1")
for each obj in colGroup
  igroups(i)=obj.Name
  i=i+1
next
'===============
'Get all of the names within each group
dim strLocal(300)
k=0
Set oLocation = CreateObject("WbemScripting.SWbemLocator") 
Set oServices = oLocation.ConnectServer(, "root\cimv2" ) 

'group name, domain name, user or group
for j = 0 to i-1

squery = "select partcomponent from win32_groupuser where groupcomponent = ""\\\\" &_
 strComputer & "\\root\\cimv2:Win32_Group.Domain=\""" & strComputer &_
 "\"",Name=\""" &igroups(j) & "\""""" 

Set oInstances = oServices.ExecQuery(sQuery) 
 FOR EACH oObject in oInstances 
  strLocal(k)=igroups(j) & "!" & oObject.PartComponent

  k=k+1

 Next
next
'==================
'Drop that into a custom wmi Namespace
'==================


' Create data class structure 
Set oDataObject = oServices.Get 
oDataObject.Path_.Class = "CM_LocalGroupMembers" 
oDataObject.Properties_.add "Account" , wbemCimtypeString 
oDataObject.Properties_("Account").Qualifiers_.add "key" , True 
oDataObject.Properties_.add "Domain" , wbemCimtypeString
oDataObject.Properties_.add "Category" , wbemCimtypeString
oDataObject.Properties_.add "Type" , wbemCimtypeString
oDataObject.Properties_.add "Name" , wbemCimtypeString
oDataObject.Properties_("Name").Qualifiers_.add "key" , True
oDataObject.Put_ 

For m = 0 To k-1
Set oNewObject = oServices.Get("CM_LocalGroupMembers" ).SpawnInstance_ 
str0 = Split(strLocal(m), "!", -1, 1)
str1 = Split(str0(1), "," , -1, 1) 
str2 = Split(str1(0), "\" , -1, 1) 
str4 = Split(str2(4), Chr(34), -1, 1) 


' The Account name or Group Name is inside the quotes after the comma 
str3 = Split(str1(1), Chr(34), -1, 1) 
' if the wmi source name is the same as the domain name inside the quotes, it' s a local account 
' str2(2) is the wmi source name, str4(1) is the domain name inside the quotes. 
If lcase(str2(2)) = lcase(str4(1)) Then 
oNewObject.Type = "Local" 
Else 
oNewObject.Type = "Domain" 
End If
oNewObject.Domain = str4(1) 
oNewObject.Account = str3(1) 
oNewObject.Name = str0(0)
Select Case lcase(str4(0))
  case "cimv2:win32_useraccount.domain="
   oNewObject.Category = "UserAccount"
  Case "cimv2:win32_group.domain="
   oNewObject.Category = "Group"
  Case "cimv2:win32_systemaccount.domain="
   oNewObject.Category = "SystemAccount"
  case else
   oNewObject.Category = "unknown"
end select
oNewObject.Put_ 
Next
wscript.echo "ok"

 end if
Next

'==================
'Done with groups.
'onto Local Users

'==================
'Delete class if exists

Set oServices = oLocation.ConnectServer(,"root\cimv2") 
set oNewObject = oServices.Get("CM_LocalUsers") 
oNewObject.Delete_ 

'==================
'Get the local User Names
'==================

dim objNet, adsCompPath, compFilter, compObj, userObj
set objNet = createobject("WScript.NetWork")
adsCompPath = "WinNT://" & objNet.ComputerName
set objNet = nothing

compFilter = array("User")
set compObj = getobject(adsCompPath)

'==========================================================
 '== apply the filter to the returned object
 '==========================================================
 compObj.filter = compFilter

'==========================================================
 '== ignore any of the attribute not present errors
 '==========================================================
 on error resume next

'==================
'Drop that into a custom wmi Namespace
'==================
' Create data class structure 
Set oDataObject = oServices.Get 
oDataObject.Path_.Class = "CM_LocalUsers" 
oDataObject.Properties_.add "AccountDisabled" , wbemCimtypeBoolean 
oDataObject.Properties_.add "IsAccountLocked" , wbemCimtypeBoolean
oDataObject.Properties_.add "LastLogin" , wbemCimtypeString
oDataObject.Properties_.add "Name" , wbemCimtypeString
oDataObject.Properties_("Name").Qualifiers_.add "key" , True
oDataObject.Properties_.add "PasswordExpirationDate" , wbemCimtypeString
oDataObject.Properties_.add "PasswordRequired" , wbemCimtypeBoolean
oDataObject.Put_ 

for each userObj in compObj
Set oNewObject = oServices.Get("CM_LocalUsers" ).SpawnInstance_ 
	oNewObject.AccountDisabled = userObj.AccountDisabled
	oNewObject.IsAccountLocked = userObj.IsAccountLocked
	oNewObject.LastLogin = userObj.LastLogin
	oNewObject.Name = userObj.Name
	oNewObject.PasswordExpirationDate = userObj.PasswordExpirationDate
	oNewObject.PasswordRequired = userObj.PasswordRequired
    oNewObject.Put_ 
Next



'==========================================================
 '== dump the reference to the domain
 '==========================================================
 set compObj = nothing

wscript.quit

Here is my MOF edit as well:

//=====================Local Group Members, Includes Administrators 
//Pre-requisite: recurring Advertisement, or Recurring DCM Baseline/CI 
//==================================================================== 
#pragma deleteclass ("LocalGroupMembers",NOFAIL) 
[ SMS_Report     (TRUE), 
  SMS_Group_Name ("LocalGroupMembers"), 
  SMS_Class_ID   ("CUSTOM|LocalGroupMembers|1.0") ] 
class cm_LocalGroupMembers : SMS_Class_Template 
{ 
    [SMS_Report (TRUE), key ] string Account; 
    [SMS_Report (TRUE)      ] string Category; 
    [SMS_Report (TRUE)      ] string Domain; 
    [SMS_Report (TRUE), key ] string Name; 
    [SMS_Report (TRUE)      ] string Type; 
}; 


//=====================Local Users
//Pre-requisite: recurring Advertisement, or Recurring DCM Baseline/CI 
//==================================================================== 
#pragma deleteclass ("LocalUsers",NOFAIL) 
[ SMS_Report     (TRUE), 
  SMS_Group_Name ("LocalUsers"), 
  SMS_Class_ID   ("CUSTOM|LocalUsers|1.0") ] 
class CM_LocalUsers : SMS_Class_Template 
{ 
    [SMS_Report (TRUE)      ] string AccountDisabled; 
    [SMS_Report (TRUE)      ] string IsAccountLocked; 
    [SMS_Report (TRUE)      ] string LastLogin; 
    [SMS_Report (TRUE), key ] string Name; 
    [SMS_Report (TRUE)      ] string PasswordExpirationDate; 
    [SMS_Report (TRUE)      ] string PasswordRequired;
}; 

Sherry posted a couple SQL statements for reports based on Local Group Membership.  Here are the ones I wrote for Local User Password Expiration:

declare @olddcm datetime 
declare @oldhinv datetime
set @oldDCM=DATEADD(DAY,-3, getdate())
set @oldHinv=DATEADD(DAY,-3, getdate())
select distinct sys1.netbios_name0
,lu.name0 [Name of the local User]
,lu.PasswordExpirationDate0 as [Password Expiration Date]
, case when lu.PasswordRequired0 = 1 then 'True'
	when lu.PasswordRequired0 = 0 then 'False' end as [Password Required]
, case when lu.IsAccountLocked0 = 1 then 'True'
	when lu.IsAccountLocked0 = 0 then 'False' end as [Account Locked]
, case when lu.AccountDisabled0 = 1 then 'True'
	when lu.AccountDisabled0 = 0 then 'False' end as [Account Disabled]
, lu.LastLogin0 as [Last Login]
, case when ws.lasthwscan < @oldhinv then 'Last Hinv might be out of date' 
 when cs.lastcompliancemessagetime < @olddcm then 'CI evaluation might be out of date'
 when ws.lasthwscan < cs.lastcompliancemessagetime then 'CI evaluated since hinv, not necessarily unreliable'
  else 'Recent CI Eval, Hinv since CI Eval = Fairly Reliable'
end as [Reliability of Information]
from
v_GS_LocalUsers0 lu
join v_gs_workstation_status ws on ws.resourceid=lu.resourceid
join v_r_system_valid sys1 on sys1.resourceid=LU.resourceid
left join v_CICurrentComplianceStatus cs on cs.resourceid=LU.resourceid
left join v_LocalizedCIProperties_SiteLoc loc on loc.ci_id=cs.ci_id
where loc.displayname = 'local users and group members into WMI'
and LU.name0 like @UserName and sys1.netbios_name0 like @MachineName
order by sys1.netbios_name0

The above code takes two prompts. 

@Machinename prompt

select distinct sys1.netbios_name0
from
v_gs_localusers0 lgm
join v_gs_workstation_status ws on ws.resourceid=lgm.resourceid
join v_r_system_valid sys1 on sys1.resourceid=lgm.resourceid
left join v_CICurrentComplianceStatus cs on cs.resourceid=lgm.resourceid
left join v_LocalizedCIProperties_SiteLoc loc on loc.ci_id=cs.ci_id
where loc.displayname = 'local users and group members into WMI'
order by sys1.netbios_name0

@UserName prompt

select distinct name0 from v_GS_LocalUsers0
order by name0

Using PowerShell to get Share and NTFS permissions

I am teaching a class this week at Benchmark Learning and had a great student question. “How do I get share permissions AND NTFS permissions” Well, look no further. The Get-SharePermission function was found here: http://social.technet.microsoft.com/Forums/en-ZA/ITCG/thread/64cabd85-7170-4678-96b5-2c516cc3b772

function Get-SharePermission
	{
  Param($Server = $env:COMPUTERNAME)
  $ShareSecurity = Get-WmiObject win32_LogicalShareSecuritySetting -ComputerName $Server   
  foreach($Share in $ShareSecurity)
  	{
   	$sharenames = $Share.Name
   	$ACLS = $Share.GetSecurityDescriptor().Descriptor.DACL
   	foreach($ACL in $ACLS)
    	{
    	$User = $ACL.Trustee.Name
    	switch ($ACL.AccessMask)
     		{
     		2032127   {$Perm = “Full Control”}
     		1245631   {$Perm = “Change”}
     		1179817   {$Perm = “Read”}
     		}
    	$myObj = “” |Select-Object ShareName,User,Permission, NTFS_User, NTFS_Rights
    	$myObj.ShareName = $sharenames
    	$myObj.User = $User
    	$myObj.Permission = $Perm
    	$myObj     
    	}
   	}
 }
 
 # Usage
 #$servers = “DC1″
 #Get-SharePermission -Server $servers
 #Get-SharePermission -Server $servers | where {$_.User -eq “everyone”}
 #$sharename = foreach ($i in Get-SharePermission -Server $servers | where {$_.User -eq “everyone”}) {$i.sharename}
 #foreach ($i in $sharename) {Get-Acl \\$Servers\$i | fl}
 #foreach ($i in $sharename) {Get-Acl \\$Servers\$i |fl @{Label=”Path”; Expression={$_.Path.substring(38)}}, owner, group, accesstostring}

PowerShell and rounding. Math is hard!

I had a student question regarding a function he wrote.  The function basically displayed disk info (disk size, free disk space and percent free), but we couldn’t get it to round the numbers.  In this first example, the numbers are not rounded:

Function Get-DiskInfo
    {        
    param ($System =".")
    $display = @{Label = "Drive" ; Expression={$_.DeviceID}},`
    @{Label = "File System"; Expression={$_.FileSystem}},`
    @{Label = "Size(GB)"; Expression={ $_.Size / 1gb }},`
    @{Label = "Free Space(GB)"; Expression={$_.FreeSpace / 1gb}},`
    @{Label = "% Free"; Expression = { ($_.FreeSpace / $_.Size) * 100}}
    Get-WmiObject -Class win32_LogicalDisk -Filter "DriveType = '3'" -ComputerName $System | Format-Table $display -auto
    }

We then tried to use the {N:02} way of rounding, but it didn’t show any results.  Example using the {N:02} on the Size(GB) column:

Function Get-DiskInfo
    {        
    param ($System =".")
    $display = @{Label = "Drive" ; Expression={$_.DeviceID}},`
    @{Label = "File System"; Expression={$_.FileSystem}},`
    @{Label = "Size(GB)"; Expression={ "{N:02}" -f $_.Size / 1gb }},`
    @{Label = "Free Space(GB)"; Expression={$_.FreeSpace / 1gb}},`
    @{Label = "% Free"; Expression = { ($_.FreeSpace / $_.Size) * 100}}
    Get-WmiObject -Class win32_LogicalDisk -Filter "DriveType = '3'" -ComputerName $System | Format-Table $display -auto
    }

After a bit of Googling I discovered the [MATH]::round function. 

Function Get-DiskInfo
    {       
    param ($System =".")
    $display = @{Label = "Drive" ; Expression={$_.DeviceID}},`
    @{Label = "File System"; Expression={$_.FileSystem}},`
    @{Label = "Size(GB)"; Expression={ [Math]::Round($_.Size / 1gb,2)}},`
    @{Label = "Free Space(GB)"; Expression={[Math]::Round($_.FreeSpace / 1gb,2)}},`
    @{Label = "% Free"; Expression = {[Math]::Round($_.FreeSpace / $_.Size * 100,2)}}
    Get-WmiObject -Class win32_LogicalDisk -Filter "DriveType = '3'" -ComputerName $System | Format-Table $display -auto
    }

Updated SCCM Computer Startup Script

In the past I have posted a VBScript that I use to install the SCCM Client and check SCCM Client health.  The updates that I have are related to fixing broken WMI.  The script is put in a GPO as a Computer Startup Script.

 

' NAME: SCCM_Client_Health_Check
' AUTHOR: Matthew Teegarden
' DATE  : 08/25/2010
' Based on the script by Chris Stauffer http://myitforum.com/cs2/blogs/cstauffer/archive/2009/12/18/sccm-sp2-health-check-startup-script-1-7.aspx
' COMMENT: Version 1.1
' 	1.0 - initial script
' 	1.1 - complete re-write.  added WMI check / Fix

Option Explicit
On Error Resume Next

Dim WshShell ' Wscript.shell
Dim fso ' FileSystemObject
Dim StrScanRun ' used for incremental count of the amount of times this script has run
Dim StrSCCMPath ' used for the location of SCCM client
Dim CCMSetupFolder ' used for the location of the CCMSetup folder
Dim SMSClientVersion ' used for storing SCCM Client Version
Dim InstallArgs ' used for SCCM Client installation switches
Dim ComSpec ' WshShell.ExpandEnvironmentStrings("%COMSPEC%")
Dim smsinstall ' SCCM Installation command
Dim strAdmAcct ' used for storing the AD Group that needs to be in the local administrators group
Dim strDomain ' stores the domain of the AD Group that needs to be in the local administrators group
Dim strGroupName ' stores the AD Group name that needs to be in the local administrators group
Dim objLocalGroup ' stores the Administrators local group
Dim strComputerName ' used for storing the computer name
Dim gstrSiteCode ' used to determine the site code of the strComptuerName
Dim Results ' used to store service state
Dim sFolder ' used to store folder path
Dim oFolder ' used to store specific folders
Dim oFile ' used for specific files
Dim WBEMFolder ' used for the wbem repository
Dim startdate ' used for SMSProvide log file access time
Dim enddate ' used for comparing the current time with last access time of the SMSProvider log file
Dim diffdate ' used to store the difference between startdate and enddate
Dim colItems ' used in For Each loops
Dim objItem ' used in For Each loops
Dim bAlreadyExists ' stores TRUE or FALSE values for strAdmAcct in the local Administrators group
Dim CurrentDirectory ' stores the location that the script is running from
Dim ScriptFullName ' stores the scripts full name.  Used with CurrentDirectory
Dim objWMI ' Used for the WMI service
Dim returncode ' used to store return codes of functions
Dim servicename ' used to pass a service name into functions
Dim Started, Stopped ' used for starting and stopping services
Dim StrSCCMInstall ' counter for how many times SCCM Client has been installed
Dim AssignedSite ' used for SCCM site assignment
Dim AutoAssignedSite ' used for auto site assignment
Dim SmsClient ' used for the SCCM WMI namespace
Dim strValueName ' used for storing registry values during the History Shift function
Dim strLogging ' used for turning logging on or off
Dim logfile ' used to write to the log file
Dim strKeyPath ' used to find the value (if exists) in the registry if the DISABLECACHEOPT and DISABLESITEOPT option was used during install
Dim strEntryName ' used to find the value (if exists) in the registry if the DISABLECACHEOPT and DISABLESITEOPT option was used during install
Dim strValue  ' ' used to find the value (if exists) in the registry if the DISABLECACHEOPT and DISABLESITEOPT option was used during install
Dim WMIisCorrupt ' used to determine if WMI is functional
Dim SomethingIsWrong ' used to determine is something is wrong!
Dim booOverWrite 

Set WshShell = CreateObject ("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")

'===========File System Constants==================================
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const OverwriteExisting = True
Const HARD_DISK = 3
'===========Registry Constants=====================================
Const HKEY_LOCAL_MACHINE = &H80000002

InstallArgs = " SMSSITECODE=AUTO SMSCACHESIZE=4096"' only needed if you have not extended AD other wise enter SCCM Client Install aguments
strAdmAcct = "DOMAIN/GROUP"	'Specify Desktop SMS Admin account domain/account
strDomain = "DOMAIN"
strGroupName = "GROUP"
strComputerName = WshShell.ExpandEnvironmentStrings("%computername%")
ComSpec = WshShell.ExpandEnvironmentStrings("%COMSPEC%")
strLogging = "enabled"

' Log file
If strLogging = "enabled" Then
	Set logfile = fso.OpenTextFile("c:\windows\temp\ConfigMgrClient.Log",ForWriting,True)
	logfile.Writeline ""
	logfile.Writeline Now
	logfile.Writeline ""
End If	

'WMI Test
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colItems = objWMI.ExecQuery ("Select * from Win32_Service Where Name = 'WinMgmt'")
For Each objItem In colItems
	Results = objItem.name
Next
If Results = "" Or IsNull(results) Then 
	If strLogging = "enabled" Then
		logfile.Writeline "WMI Is Corrupt"
	End If
	WMIisCorrupt = "True"
	CheckSCCMInstall
	AdvCliInst(ComSpec)
	WScript.Quit
Else
	If strLogging = "enabled" Then
		logfile.Writeline "WMI is good"
	End If
Set Results = nothing
End If

' Get Local CCM Path
StrSCCMPath = WshShell.RegRead("HKLM\SOFTWARE\Microsoft\SMS\Client\Configuration\Client Properties\Local SMS Path")
If StrSCCMPath = "" Or IsNull (StrSCCMPath) Then 
	StrSCCMPath = WshShell.RegRead("HKLM\SOFTWARE\Wow6432Node\Microsoft\SMS\Client\Configuration\Client Properties\Local SMS Path")
End If	
If strLogging = "enabled" Then
	logfile.Writeline "Get local CCM Path = " & StrSCCMPath
End If
If StrSCCMPath = "" Or IsNull (StrSCCMPath) Then
	CheckSCCMInstall
	AdvCliInst(ComSpec)
	WScript.Quit
End If

' Check for SCCM Helath Check registry key and create it if it doesn't exist 
StrScanRun = WshShell.RegRead("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\Scan_Run")
If StrScanRun = "" Or IsNull (StrScanRun) Then 
	StrScanRun = WshShell.RegRead("HKLM\SOFTWARE\Wow6432Node\SCCM\SCCM_Health_Check\Scan_Run")
End If	
If StrScanRun = "" Or IsNull (StrScanRun) Then
	WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\Scan_Run"), "0"
End If	

' Write current time to the registry
WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\Last_Run"), Now()

' Check for CCMEXEC service
Results = ServiceState("ccmexec")'Check CCM Status
If strLogging = "enabled" Then
	logfile.Writeline "SMS Agent Host = " & Results
End If
If LCase(Results) = LCase("Running")Then
	WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\CCM_Service_Check"), "Running"
	If strLogging = "enabled" Then
		logfile.Writeline "SMS Agent Host = " & Results
	End If
' CCMExec serivice is running.  Do SCCM Health checks			
	Check_Client_info  'Check Client Variable	    			
	CheckSitecode      'Check Client SiteCode
	ClientVersionCheck 'Check Client Versiont 
ElseIf LCase(Results) = LCase("Stopped")Then
	If strLogging = "enabled" Then
		logfile.Writeline "SMS Agent Host = " & Results
  End If
	set Results = Nothing
	Call EnableService("ccmexec") 
	KickService("ccmexec")
	WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\CCM_Service_Check"), "CCM Service was Stopped"
	' CCMExec serivice is running.  Do SCCM Health checks					    		
	Check_Client_info 'Check Client Variable	    			
	CheckSitecode      'Check Client SiteCode
	ClientVersionCheck 'Check Client Version
ElseIf Results = "" Or IsNull (Results) Then
	If strLogging = "enabled" Then
		logfile.Writeline "SMS Agent Host not found"
  End If
	WMIisCorrupt = "True"
	CheckSCCMInstall
	AdvCliInst(ComSpec)
	WScript.Quit
End If

CheckSCCMInstall'Check to see if CCMSetup failed and fix error
Script_increment  'Increment Registery Key For script by 1 And move present value To history 		
Check_AdminShare ' Check Admin$ Share
Check_SMSLOCALADMIN'Check Local Admin account
WS-- USEnabled ' check to ensure windows update service is enabled

Function CheckSCCMInstall  
	On Error Resume Next
	booOverWrite = vbFalse
	CurrentDirectory = replace(WScript.ScriptFullName,WScript.ScriptName,"")
	If strLogging = "enabled" Then
		logfile.Writeline  "Starting CheckSCCMInstall with directory " & CurrentDirectory
	End If
	If fso.FolderExists("C:\Windows\System32\CCMSetup\LastError") Or fso.FolderExists("C:\Windows\CCMSetup\LastError") or WMIisCorrupt = "True"  or SomethingIsWrong = "True" Then
		If strLogging = "enabled" Then
			logfile.Writeline  "LastError folder exists or Can not connect to WMI.  Deinstalling client and reinstalling"
		End If
'     Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
'     Set colItems = objWMI.ExecQuery ("Select * from Win32_Service Where Name = 'CCMSETUP'")
' 		For Each objItem In colItems
' 			objItem.StopService()
' 		Next
	  WshShell.Run("Net Stop CCMSetup /Y"), 0, True
		If strLogging = "enabled" Then
			logfile.Writeline  "Stopped CCMSEtup service if existed"
		End If
' ' 		Set colItems = objWMI.ExecQuery ("Select * from Win32_Process Where Name = 'CCMSETUP.EXE'")
' ' 		For Each objItem In colItems
' ' 			objItem.Terminate()
' ' 		Next
' 		oFile = CurrentDirectory & "PSKILL.EXE"
' 		If strLogging = "enabled" Then
' 			logfile.Writeline  "Copying " & oFile
' 		End If
' 		fso.CopyFile oFile, "C:\Windows\Temp\", booOverWrite
' 		'WScript.Sleep 10000
' 		WshShell.Run "c:\Windows\Temp\pskill ccmsetup",,True
' 		If strLogging = "enabled" Then
' 			logfile.Writeline  "Stopped CCMSEtup process if existed"
' 		End If
		oFile = CurrentDirectory & "ccmclean.exe"
		If strLogging = "enabled" Then
			logfile.Writeline  "Copying " & oFile
		End If
		fso.CopyFile oFile, "C:\Windows\Temp\", booOverWrite
		'WScript.Sleep 10000
		WshShell.Run "c:\Windows\Temp\CCMClean /all /q",,True
		If strLogging = "enabled" Then
			logfile.Writeline  "Ran CCMClean 1"
		End If
		WshShell.Run "c:\Windows\Temp\CCMClean /all /q",,True
		If strLogging = "enabled" Then
			logfile.Writeline  "Ran CCMClean 2"
		End If
		oFile = CurrentDirectory & "ccmdelcert.exe"
		If strLogging = "enabled" Then
			logfile.Writeline  "Copying " & oFile
		End If
		fso.CopyFile oFile, "C:\Windows\Temp\", booOverWrite
		'WScript.Sleep 10000
		WshShell.Run "c:\Windows\Temp\ccmdelcert.exe",,True
		If strLogging = "enabled" Then
			logfile.Writeline  "Ran CCMDelCert"
		End If
		fso.DeleteFile "C:\windows\SMSCFG.INI", True
		If strLogging = "enabled" Then
			logfile.Writeline  "Delete SMSCFG.INI"
		End If
'     Set colItems = objWMI.ExecQuery("Associators of " _
' 			& "{Win32_Service.Name='Winmgmt'} Where " _
' 			& "AssocClass=Win32_DependentService " & "Role=Antecedent" )
' 		For Each objItem In colItems 
' 			objItem.StopService()
' 		Next
' 		WScript.Sleep 20000
' 		Set colItems = objWMI.ExecQuery _
' 			("Select * from Win32_Service where Name='Winmgmt'")
' 		For Each objItem In colItems
' 			objItem.StopService()
' 		Next
		WshShell.Run("C:\Windows\System32\regsvr32.exe c:\windows\system32\atl.dll /s"),0, True
		WshShell.Run("C:\Windows\System32\rundll32.exe wbemupgd, UpgradeRepository"), 0, True
		If strLogging = "enabled" Then
			logfile.Writeline  "Ran C:\Windows\System32\rundll32.exe wbemupgd, UpgradeRepository"
		End If
		WScript.Sleep 60000
		Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
		Set colItems = objWMI.ExecQuery ("Select * from Win32_Service Where Name = 'WinMgmt'")
		For Each objItem In colItems
			Results = objItem.name
		Next
		If Results = "" Or IsNull(results) Then 
			If strLogging = "enabled" Then
				logfile.Writeline "WMI Is STILL Corrupt"
			End If
			WshShell.Run("Net Stop Winmgmt /Y"), 0, True
			If strLogging = "enabled" Then
				logfile.Writeline  "Stopped Winmgmt"
			End If	
			fso.DeleteFolder ("C:\Windows\System32\WBEM\Repository"), True
			If strLogging = "enabled" Then
				logfile.Writeline  "Deleted Repository"
			End If
			WshShell.Run("Net Start Winmgmt"), 0, True
			If strLogging = "enabled" Then
				logfile.Writeline  "Started Winmgmt"
			End If
			sFolder = WshShell.ExpandEnvironmentStrings("%windir%\System32\WBEM")
			Set oFolder = fso.GetFolder(sFolder)
			For Each oFile In oFolder.Files
				Select Case lCase(fso.GetExtensionName(oFile))
	  			Case "mof", "mfl"
	   			WshShell.Run oFolder & "\mofcomp.exe """ & oFile & """", 0, True
	   			If strLogging = "enabled" Then
						logfile.Writeline  "Compiled " & oFile
					End If
				End Select
			Next
			WshShell.Run("C:\Windows\System32\rundll32.exe wbemupgd, UpgradeRepository"), 0, True
			If strLogging = "enabled" Then
				logfile.Writeline  "Ran C:\Windows\System32\rundll32.exe wbemupgd, UpgradeRepository"
			End If		
			WScript.Sleep 60000
		End If
		fso.DeleteFolder ("C:\Windows\System32\CCMSetup"), True
		fso.DeleteFolder ("C:\Windows\CCMSetup"), True
		fso.DeleteFolder ("C:\Windows\System32\CCM"), True
		fso.DeleteFile ("C:\Windows\Temp\ccmclean.exe"), True
		fso.DeleteFile ("C:\Windows\Temp\ccmdelcert.exe"), True
' 		fso.DeleteFile ("C:\Windows\Temp\PSKILL.exe"), True
	End If
	If strLogging = "enabled" Then
		logfile.Writeline  "Ending CheckSCCMInstall"
	End If
End Function	

Function Check_Client_info
	On Error Resume Next
	If strLogging = "enabled" Then
		logfile.Writeline  "Starting Check_Client_info"
	End If
	Set SmsClient = GetObject("winmgmts:ROOT/CCM:SMS_Client=@")
	SMSClientVersion = SmsClient.ClientVersion
	If SMSClientVersion = "" Or IsNull (SMSClientVersion) Then
		SMSClientVersion = WshShell.RegRead("HKLM\SOFTWARE\Microsoft\SMS\Mobile Client\ProductVersion")
	End If
	If strLogging = "enabled" Then
		logfile.Writeline  "Ending Check_Client_info"
	End If
End Function	

Function Script_increment
	On Error Resume Next
	If strLogging = "enabled" Then
		logfile.Writeline  "starting Script_increment"
	End If
	StrScanRun = WshShell.RegRead("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\Scan_Run")
	If StrScanRun = "" Or IsNull (StrScanRun) Then
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\Scan_Run"), "0"
	Else
		StrScanRun = StrScanRun + 1
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\Scan_Run"), StrScanRun
	End If
	If StrScanRun >= 2 Then
		History_Shift
	End If
	If strLogging = "enabled" Then
		logfile.Writeline  "Ending Script_increment"
	End If
End Function	

Function Check_AdminShare
On Error Resume Next
	If strLogging = "enabled" Then
		logfile.Writeline  "starting Check_AdminShare "
	End If	
	Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
	Set colItems = objWMI.ExecQuery("Select * from Win32_Share Where Name = 'ADMIN$'")
	If colItems.Count > 0 Then
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\AdminShare_Check"), "Admin$ is present"
		If strLogging = "enabled" Then
			logfile.Writeline "Admin$ is present"
		End If
	Else
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\AdminShare_Check"), "Admin$ Is missing"
		If strLogging = "enabled" Then
			logfile.Writeline "Admin$ is missing"
		End If
		Set colItems = objWMI.execquery("select state from win32_service where name='LanmanServer'")
		For Each objItem In colItems
			objItem.StopService
		Next
		Do Until Stopped = True
			Set colItems = objWMI.execquery("select state from win32_service where name='LanmanServer'")
			For Each objItem In colItems
				If lcase(objItem.State) = lcase("Stopped") Then
					Stopped = True
				End If
			Next
		Loop
		Set colItems = objWMI.execquery("select state from win32_service where name='LanmanServer'")
		For Each objItem In colItems
			objItem.StartService
		Next
	End If	
	If strLogging = "enabled" Then
		logfile.Writeline  "ending Check_AdminShare "
	End If	
End Function

Function Check_SMSLOCALADMIN
	On Error Resume Next
	If strLogging = "enabled" Then
		logfile.Writeline  "starting  Check_SMSLOCALADMIN"
	End If	
	Set objLocalGroup = GetObject("WinNT://" & strComputerName & "/Administrators, group")
	For Each objItem In objLocalGroup.Members 
	If InStr(UCase(objItem.ADSPath),UCase(strDomain & "/" & strGroupName)) <> 0 Then
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\Account_Check"), strAdmAcct & " is in the Admins group"
		If strLogging = "enabled" Then
			logfile.Writeline strAdmAcct & " is in the Admins group"
		End If
		bAlreadyExists = True
	End If
	Next
	If bAlreadyExists <> True Then
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\Account_Check"), strAdmAcct & " was not in Admins group - adding"
		If strLogging = "enabled" Then
			logfile.Writeline  strAdmAcct & " was not in Admins group - adding"
		End If
		objLocalGroup.Add("WinNT://" & strDomain & "/" & strGroupName)
	End If  
	If strLogging = "enabled" Then
		logfile.Writeline  "starting  Check_SMSLOCALADMIN"
	End If	
End Function

Function WS-- USEnabled
	On Error Resume Next
	If strLogging = "enabled" Then
		logfile.Writeline  "starting WS-- USEnabled"
	End If
	Results = ServiceState("wuauserv")'Check Windows Update Status
	If LCase(Results) = LCase("Running")Then
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\WindowsUpdate_Service_Check"), "Running"
		If strLogging = "enabled" Then
			logfile.Writeline "Auto Updates Serivice = " & Results
		End If
	ElseIf LCase(Results) = LCase("Stopped")Then
		If strLogging = "enabled" Then
			logfile.Writeline "Auto Updates Serivice = " & Results
		End If
		Call EnableService("wuauserv") 
		KickService("wuauserv")
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\WindowsUpdate_Service_Check"), "Windows Update Service was Stopped"
	End If
	Set Results = Nothing
	If strLogging = "enabled" Then
		logfile.Writeline  "ending WS-- USEnabled"
	End If
End Function	 

Function ClientVersionCheck 
	On Error Resume Next
	If strLogging = "enabled" Then
		logfile.Writeline  "starting ClientVersionCheck "
	End If
	If SMSClientVersion = "" Then
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\CCM_Client_Check"), "Client Not Installed"
		If strLogging = "enabled" Then
			logfile.Writeline "SMSClientVersion = NO CLIENT"
		End If
		Call AdvCliInst(ComSpec)
		WScript.Quit
	Else
		If strLogging = "enabled" Then
			logfile.Writeline "SMSClientVersion = " & SMSClientVersion
		End If
		Select Case SMSClientVersion
				' RTM 4.00.5931.0001
				' SP1 4.00.6221.1000
				' SP2 4.00.6487.2000
				' R3  4.00.6487.2157
			Case "4.00.6487.2157" ' SCCM SP2 R3 client version
				PolicyEval
				ContentTransferMangerEval
				InventoryAgentEval
			Case "4.00.6487.2000" ' SCCM SP2 client version
				If strLogging = "enabled" Then
					logfile.Writeline "Needs R3 hotfix"
				End If
				CurrentDirectory = replace(WScript.ScriptFullName,WScript.ScriptName,"")
				smsinstall =ComSpec & " /c msiexec.exe /p "& CurrentDirectory & "SMSClient\i386\hotfix\KB977384\sccm2007ac-sp2-kb977384-x86-enu.msp /L*v %TEMP%\sccm2007ac-sp2-kb977384-x86-enu.msp.LOG /q REINSTALL=ALL REINSTALLMODE=mous"
			  WshShell.Run smsinstall,0,False
			  If strLogging = "enabled" Then
					logfile.Writeline "Install R3 hotfix"
				End If
				PolicyEval
				ContentTransferMangerEval
				InventoryAgentEval
		Case Else
			If strLogging = "enabled" Then
				logfile.Writeline  "ClientVersionCheck could not determine client version - installing client"
			End If
' 			WshShell.Run("Net Stop CCMSetup /Y"), 0, True
' 			If strLogging = "enabled" Then
' 				logfile.Writeline  "Stopped CCMSEtup service if existed"
' 			End If
' ' 		Set colItems = objWMI.ExecQuery ("Select * from Win32_Process Where Name = 'CCMSETUP.EXE'")
' ' 		For Each objItem In colItems
' ' 			objItem.Terminate()
' ' 		Next
			oFile = CurrentDirectory & "PSKILL.EXE"
			fso.CopyFile oFile, "C:\Windows\Temp", True
			WshShell.Run "c:\Windows\Temp\pskill ccmsetup",,True
			If strLogging = "enabled" Then
				logfile.Writeline  "Stopped CCMSEtup process if existed"
			End If
			oFile = CurrentDirectory & "ccmclean.exe"
			fso.CopyFile oFile, "C:\Windows\Temp", True
			WshShell.Run "c:\Windows\Temp\CCMClean /all /q",,True
			If strLogging = "enabled" Then
				logfile.Writeline  "Ran CCMClean 1"
			End If
			WshShell.Run "c:\Windows\Temp\CCMClean /all /q",,True
			If strLogging = "enabled" Then
				logfile.Writeline  "Ran CCMClean 2"
			End If
			oFile = CurrentDirectory & "ccmdelcert.exe"
			fso.CopyFile oFile, "C:\Windows\Temp", True
			WshShell.Run "c:\Windows\Temp\ccmdelcert.exe",,True
			If strLogging = "enabled" Then
				logfile.Writeline  "Ran CCMDelCert"
			End If
			fso.DeleteFile "C:\windows\SMSCFG.INI", True
			If strLogging = "enabled" Then
				logfile.Writeline  "Delete SMSCFG.INI"
			End If
			fso.DeleteFolder ("C:\Windows\System32\CCMSetup"), True
			fso.DeleteFolder ("C:\Windows\CCMSetup"), True
			fso.DeleteFile ("C:\Windows\Temp\ccmclean.exe"), True
			fso.DeleteFile ("C:\Windows\Temp\ccmdelcert.exe"), True
			fso.DeleteFile ("C:\Windows\Temp\PSKILL.exe"), True
      Call AdvCliInst(ComSpec)
      WScript.Quit
    End Select
	End If
	If strLogging = "enabled" Then
		logfile.Writeline  "ending ClientVersionCheck "
	End If
End Function	   

Function PolicyEval 	
	On Error Resume Next	
	If strLogging = "enabled" Then
		logfile.Writeline  "starting PolicyEval  "
	End If
	Set oFile = fso.GetFile (StrSCCMPath & "Logs\CCMExec.log")
	startdate = ofile.DateLastModified
	enddate = date()
	If isDate(startdate) Then
		diffdate = DateDiff("d", startdate, enddate)
		If strLogging = "enabled" Then
			logfile.Writeline "CCMExec.log last accessed = " & diffdate
		End If
	End If
	If diffdate > 21 Then
		If strLogging = "enabled" Then
			logfile.Writeline "CCMExec.log last accessed more than 21 days ago. Repair client"
		End If
		SomethingIsWrong = "True"
		call CheckSCCMInstall
		call AdvCliInst(ComSpec)
		wscript.quit
	End If
	If strLogging = "enabled" Then
		logfile.Writeline  "ending PolicyEval  "
	End If
End Function	

Function ContentTransferMangerEval	
	On Error Resume Next	
	If strLogging = "enabled" Then
		logfile.Writeline  "starting ContentTransferManager.log Eval  "
	End If
	Set oFile = fso.GetFile (StrSCCMPath & "Logs\ContentTransferManager.log")
	startdate = ofile.DateLastModified
		enddate = date()
	If isDate(startdate) Then
		diffdate = DateDiff("d", startdate, enddate)
		If strLogging = "enabled" Then
			logfile.Writeline "ContentTransferManager.log last accessed = " & diffdate
		End If
	End If
	If diffdate > 45 Then
		If strLogging = "enabled" Then
			logfile.Writeline "ContentTransferManager.log last accessed more than 45 days ago. Repair client"
		End If
		SomethingIsWrong = "True"
		call CheckSCCMInstall
		call AdvCliInst(ComSpec)
		wscript.quit
	End If
	If strLogging = "enabled" Then
		logfile.Writeline  "ending ContentTransferManager.log eval  "
	End If
End Function	 

Function InventoryAgentEval	
	On Error Resume Next	
	If strLogging = "enabled" Then
		logfile.Writeline  "starting InventoryAgent.log Eval  "
	End If
	Set oFile = fso.GetFile (StrSCCMPath & "Logs\InventoryAgent.log")
	startdate = ofile.DateLastModified
		enddate = date()
	If isDate(startdate) Then
		diffdate = DateDiff("d", startdate, enddate)
		If strLogging = "enabled" Then
			logfile.Writeline "InventoryAgent.log last accessed = " & diffdate
		End If
	End If
	If diffdate > 10 Then
		If strLogging = "enabled" Then
			logfile.Writeline "InventoryAgent.log last accessed more than 10 days ago. Repair client"
		End If
		SomethingIsWrong = "True"
		call CheckSCCMInstall
		call AdvCliInst(ComSpec)
		wscript.quit
	End If
	If strLogging = "enabled" Then
		logfile.Writeline  "ending InventoryAgent.log eval  "
	End If
End Function	   

Function CheckSitecode  
' 	On Error Resume Next	
' 	If strLogging = "enabled" Then
' 		logfile.Writeline  "starting CheckSitecode   "
' 	End If		
' 	'Ensure that the client is auto assigned to sites and that the client is assigned to the correct site
' 	Set SmsClient = CreateObject ("Microsoft.SMS.Client")
' 	AssignedSite = SmsClient.GetAssignedSite
' 	If ((Len(strComputerName) = 13) And (Mid(strComputerName, 7, 1) = "X")) Then
' 				gstrSiteCode = Mid(strComputerName, 3, 4)
' 	end If
' 	WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\SCCM_AssignedSite"), AssignedSite
' 	If strLogging = "enabled" Then
' 		logfile.Writeline "SCCM Assigned Site = " & AssignedSite
' 	End If
' 	Set objWMI = GetObject("winmgmts:ROOT/CCM:SMS_Client=@")
' 	AutoAssignedSite = objWMI.EnableAutoAssignment
' 	If AutoAssignedSite = True Then
' 		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\SCCM_AutoAssignment"), "TRUE"
' 		If strLogging = "enabled" Then
' 			logfile.Writeline "SCCM Auto Assignement = TRUE"
' 		End If
' 	Else 
' 		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\SCCM_AutoAssignment"), "FALSE"
' 		If strLogging = "enabled" Then
' 			logfile.Writeline "SCCM Auto Assignement = FALSE"
' 		End If
' 		SmsClient.EnableAutoAssignment 1
' 	End If
' 	If gstrSiteCode = "MN00" Then
' 		If AssignedSite <> "P01" Then
' 			SmsClient.SetAssignedSite("P01")
' 		End If	
' 	Else
' 		If AssignedSite <> "CEN" Then
' 			SmsClient.SetAssignedSite("CEN")
' 		End If	
' 	End If 
' 	If strLogging = "enabled" Then
' 		logfile.Writeline  "ending CheckSitecode   "
' 	End If	
End Function

Function KickService(servicename)
	On Error Resume Next
	If strLogging = "enabled" Then
		logfile.Writeline  "starting KickService " & servicename
	End If	
	Results = ServiceState(servicename)
	Set objWMI = getobject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
	If Not LCase(Results) = LCase("Running")Then
		Set colItems = objWMI.execquery("select state from win32_service where name='" & servicename & "'")
		For Each objItem In colItems
			' Start Service
			objItem.StartService
		Next
' 		Do Until Started = True
' 			Set colItems = objWMI.execquery("select state from win32_service where name='" & servicename & "'")
' 			For Each objItem In colItems
' 				If lcase(objItem.State) = lcase("Running") Then
' 					Started = True
' 				end If
' 			Next
' 		Loop
	End If 
	set Results = Nothing
	If strLogging = "enabled" Then
		logfile.Writeline  "ending KickService " & servicename
	End If	
End Function  

Function EnableService(servicename)
	On Error Resume Next
	If strLogging = "enabled" Then
		logfile.Writeline  "starting EnableService " & servicename
	End If
	Set objWMI = GetObject("winmgmts:root\cimv2:Win32_Service.Name='" & servicename & "'")
		Results = objWMI.ChangeStartMode("automatic")
	If strLogging = "enabled" Then
		logfile.Writeline  "ending EnableService " & servicename
	End If
End Function

Function ServiceState(servicename)
 	On Error Resume Next
 	If strLogging = "enabled" Then
		logfile.Writeline  "starting ServiceState " & servicename
	End If	
 	Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
   Set colItems = objWMI.execquery("select state from win32_service where name='" & servicename & "'")
   For Each objItem In colItems
   	Results = objItem.State
   Next
   If strLogging = "enabled" Then
		logfile.Writeline  servicename & " is " & Results
	 End If	
     ServiceState = Results
    set Results = Nothing
 	If strLogging = "enabled" Then
		logfile.Writeline  "ending ServiceState " & servicename
	End If	
End Function

Sub AdvCliInst(ComSpec)
	On Error Resume Next
	If strLogging = "enabled" Then
		logfile.Writeline  "starting AdvCliInst"
	End If	
	If ComSpec = "" Then
		WScript.Quit
	Else
		CurrentDirectory = replace(WScript.ScriptFullName,WScript.ScriptName,"")
		smsinstall =ComSpec & " /c "& CurrentDirectory & "SMSClient\CCMSetup.exe" & InstallArgs
		SCCM_Install
	  WshShell.Run smsinstall,0,True
	  If strLogging = "enabled" Then
			logfile.Writeline  "Starting CCMSetup"
		End If	
		Do While GetObject("WinMgmts:/root/cimV2").ExecQuery("SELECT * FROM Win32_Process WHERE Name='CCMSetup.exe'").Count
			WScript.Sleep 1000
		Loop
		If strLogging = "enabled" Then
			logfile.Writeline  "Ending CCMSetup"
		End If	
		If strLogging = "enabled" Then
			logfile.Writeline  "Starting R3 patch"
		End If	
		smsinstall =ComSpec & " /c msiexec.exe /p "& CurrentDirectory & "SMSClient\i386\hotfix\KB977384\sccm2007ac-sp2-kb977384-x86-enu.msp /L*v %TEMP%\sccm2007ac-sp2-kb977384-x86-enu.msp.LOG /q REINSTALL=ALL REINSTALLMODE=mous"
	  WshShell.Run smsinstall,0,True
	  If strLogging = "enabled" Then
			logfile.Writeline  "Ending R3 patch"
		End If	
	End If
	If strLogging = "enabled" Then
		logfile.Writeline  "ending AdvCliInst"
	End If	
End Sub

Function SCCM_Install
	On Error Resume Next 
	If strLogging = "enabled" Then
		logfile.Writeline  "starting SCCM_Install"
	End If
	StrSCCMInstall = WshShell.RegRead("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\SCCM_Install")	
	If StrSCCMInstall = "" Or IsNull (StrSCCMInstall) Then
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\SCCM_Install"), "1"
	Else
		StrSCCMInstall = WshShell.RegRead("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\SCCM_Install")
		StrSCCMInstall = StrSCCMInstall + 1
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\SCCM_Install"), StrSCCMInstall
	End If
	If strLogging = "enabled" Then
		logfile.Writeline  "Ending SCCM_Install"
	End If
End Function

Function History_Shift
	On Error Resume Next
	If strLogging = "enabled" Then
		logfile.Writeline  "starting History_Shift"
	End If
	' CCM service History move
	strValueName = WshShell.RegRead("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\CCM_Service_Check")
	If strValueName = "" Or IsNull (strValueName) Then 
		strValueName = "CCM Service was Stopped"
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\CCM_Service_Check"), strValueName
	Else
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\HS_CCM_Service_Check"), strValueName
	End If	
	Set strValueName = Nothing	
	' Admin$ Check History move	
	strValueName = WshShell.RegRead("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\AdminShare_Check")
	If strValueName = "" Or IsNull (strValueName) Then 
		strValueName = "Admin$ Is missing"
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\AdminShare_Check"), strValueName
	Else
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\HS_AdminShare_Check"), strValueName
	End If	
	Set strValueName = Nothing
	'Account Check History move		
	strValueName = WshShell.RegRead("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\Account_Check")
	If strValueName = "" Or IsNull (strValueName) Then 
		strValueName = strAdmAcct & " was not in Admins group"
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\Account_Check"), strValueName
	Else
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\HS_Account_Check"), strValueName
	End If	
	Set strValueName = Nothing
	'Windows Update Service History move		
	strValueName = WshShell.RegRead("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\WindowsUpdate_Service_Check")
	If strValueName = "" Or IsNull (strValueName) Then 
		strValueName = "Windows Update service was not running"
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\WindowsUpdate_Service_Check"), strValueName
	Else
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\HS_WindowsUpdate_Service_Check"), strValueName
	End If	
	Set strValueName = Nothing
	'SCCM_AssignedSite History move		
	strValueName = WshShell.RegRead("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\SCCM_AssignedSite")
	If strValueName = "" Or IsNull (strValueName) Then 
		strValueName = "No Assigned Site"
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\SCCM_AssignedSite"), strValueName
	Else
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\HS_SCCM_AssignedSite"), strValueName
	End If	
	Set strValueName = Nothing
	'SCCM_AutoAssignment History move		
	strValueName = WshShell.RegRead("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\SCCM_AutoAssignment")
	If strValueName = "" Or IsNull (strValueName) Then 
		strValueName = "SCCM Autoassignment failure"
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\SCCM_AutoAssignment"), strValueName
	Else
		WshShell.RegWrite ("HKLM\SOFTWARE\SCCM\SCCM_Health_Check\HS_SCCM_AutoAssignment"), strValueName
	End If	
	Set strValueName = Nothing
	If strLogging = "enabled" Then
		logfile.Writeline  "ending History_Shift"
	End If
End Function

SCCM Software Inventory–File size has exceeded the limit of 4 MB

Today I noticed a lot of NULL values for SCCM Client Software Inventory.  Here is my fix

· SCCM Client [enter machine name here] had a NULL value for Last Software Inventory

· I forced a resync of Software Inventory on the client and looked at the SINVPROC.log a few days later.

· The logs (unfortunately only last for a couple days) so…

· I went into the Inboxes\SINV\BadSINV folder and noticed a lot of files

· Ran a powershell script to find a file with [enter machine name here] in it

o select-string -path *.sic -pattern “[enter machine name here” | ft filename

· Took the file and moved it to inboxes\auth\sinv.box so that it would get processed again

· Watched the SINVPROC.LOG and noticed that the file was rejected because it was larger than 4mb

· Looked that up on the web and found the solution was to modify HKLM\Software\Microsoft\SMS\Components\SMS_SOFTWARE_INVENTORY_PROCESSOR\Max File Size

o The value I saw was set to 5mb. Don’t ask why the log file said 4mb!

o I changed it to the max size which is 50mb (according to Wally Meed – AKA SCCM God)

· Did step 6 again to find the file

· Did step 7 again

· Good to go.

Here are my references

http://social.technet.microsoft.com/Forums/en/configmgrinventory/thread/3e3df8dd-66fa-4a95-b680-b8017bf10fdc

http://www.myitforum.com/forums/tm.aspx?high=&m=206088&mpage=1#206088

http://www.myitforum.com/forums/tm.aspx?high=&m=200770&mpage=1#200770

MMS 2011–Settings management (AKA DCM)

  • Key concepts
    • Baseline – group of CI’s
    • CI’s – definition of the settings and rules
  • User and Device targeting of baselines
    • if the baseline is deployed to a ‘User’ there is an option to evaluate the baseline on every device the user logs on OR the user’s primary device
  • Automatic remediation!!!
    • only for the following
      • Registry – create the key or modify value
      • WMI and script based settings
        • If the above comes back non-compliant an administrator can define a ‘fix’ script
      • mobile settings
    • * have to select the remediation in the CI and the baseline *
  • Can easily create CI’s by browsing to a “Gold System” and generating them
    • can only browse file and registry system types from local or remote machine
  • CI’s can be created for Windows system or Mobile Systems

MMS 2011–Software Update Management

  • can now control how long before an update is expired after it has been superseded.
    • example:  Do not expire a superseded update until after ‘X’ many months
  • Security scopes and rules are now definable!

MMS 2011– Converting Existing Software Packages into the ConfigMgr 2012 Application Model

  • 2012 App Model
    • Virtual containers that contain end user metadata and administrator properties
    • Deployment Types
      • App-V
      • Scripts
      • MSI
      • Mobile Cab
    • Requirement rules
      • platform
      • hardware requirements
      • Utilizes DCM to determine applicability
    • Dependencies
      • What other applications are required in order to install
    • detection method
      • How to identify if the application is present
      • can be product code, file version, registry location
    • Content
      • source files
      • installation options
  • Application Feature Mapping from SCCM 2007 to SCCM 2012
    • Package and Programs = Application and Deployment Type
    • Advertisement = Deployment
    • Collection Rules = Requirement Rules and Global Conditions
    • Run Advertised Programs = Software Center
    • New feature – User Device Affinity (UDA)
    • New feature – Software Catalog
  • Best Practices BEFORE migration
    • In SCCM 2007
      • start using platform requirements
      • User UNC patch for Source Location
      • Use only MSI’s with one unique PID
  • Migration Options
    • Do nothing – keep packages and programs
    • Manually Convert
    • Convert using Package Conversion Manager

MMS 2011–Migrating from SCCM 2007 to SCCM 2012

  • Side by Side upgrade only. 
    • great opportunity for a hardware refresh and start with a clean environment
  • SCCM 2012 has a built in migration tool with reporting
    • migration of object
    • migration of client
    • minimize WAN impact
    • assist with flattening hierarchy Plan
    • look at current design.  Flatten hierarchy if necessary
    • Ensure that SCCM 2007 SP2 is installed on all site servers and clients
    • SCCM 2012 requires Sever 2008 (x64) and SQL 2008 SP1 (x64) (cumulative update 10)
  • Deploy
    • Install SCCM 2012 site
    • configure Software update point and sync
  • migrate
    • Using the migration feature, specify top level site of the SCCM 2007 hierarchy
      • once the connection is configured, SCCM 2012 will check SCCM 2007 every four hours to keep data accurate for migration jobs and retrieve package status from DP’s
      • create one migration for each SCCM 2007 Primary site in your hierarchy
    • Object Migration by type / instance
      • cherry pick what object to migrate
      • can migrate objects that where modified (on SCCM 2007) after they were migrated to SCCM 2012
    • Collection Migration
      • include all related objects for a collection and all object targeted to the members of the selected collection
      • can exclude collections
    • object supported for migration
      • Collections (NOT empty ones)
      • advertisements
      • boundaries
      • packages and virtual application placates
      • software updates
      • OSD
      • settings
    • Distribution Point sharing
      • utilize existing SCCM 2007 DP’s in SCCM 2012 (only for objects that you have migrated)
    • Can now (with SCCM 2012 Beta 2) upgrade 2007 DPs
      • content of migrated packages converted to SCCM 2012
      • can’t have any other site system roles on the DP.  This will be addressed in the future
      • need double the amount of disk space used to convert
      • BDP’s can’t be upgraded
    • Secondary Sites need to be uninstalled and re-installed to SCCM 2012
      • consider replacing Secondary Sites with DPs
    • All other site system roles need to be uninstalled and reinstalled to SCCM 2012
  • Client Migration
    • Clients retain execution history (so that advertisements don’t rerun!)
    • minimum supported clients:  XP SP2, Server 2003 SP2, Windows 7 and Server 2008 RTM
    • Inventory does not get migrated
  • Migration Reports are available through SSRS
  • Packages can only be migrated as long as they are using a UNC for their source location
  • OSD migration
    • OS image / package
    • task sequences
    • drivers and packages
    • Boot images are NOT migrated
    • SCCM Client installation package is NOT migrated
  • DCM migration
    • CI’s and Baselines are migrated as a new version in SCCM 2012
    • ability to import Config Packs
  • Other object that can be migrated
    • Software metering rules
    • Search and Admin folders
  • Reports
    • Reports must be manually exported to RDL files.
    • SSRS is the only reporting mechanism