SCCM Software Distribution Content download flow
SCCM Client Health Related Collections
Collection Name | WQL Query |
CCMEval – No Status | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where resourceid in (select resourceid from SMS_CH_EvalResult where SMS_CH_EvalResult.Result = 1 and DATEDIFF(day,SMS_CH_EvalResult.EvalTime,GetDate())<=7) |
CCMEval – Failed Status | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where resourceid in (select resourceid from SMS_CH_EvalResult where SMS_CH_EvalResult.Result in (3,4,5) and DATEDIFF(day,SMS_CH_EvalResult.EvalTime,GetDate())<=7) |
Client Installed but Not Approved for Use | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceId in (select ResourceID from SMS_FullCollectionMembership where IsApproved = 0 or IsApproved IS NULL) and SMS_R_System.ResourceId in (select SMS_R_SYSTEM.ResourceID from SMS_R_System Where SMS_R_System.Client = 1) |
Client Not Installed and Not Assigned* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceId not in (select SMS_R_SYSTEM.ResourceID from SMS_R_System where SMS_R_System.Client = 1) and SMS_R_System.SMSAssignedSites is null and SMS_R_System.ResourceId in (select ResourceID from SMS_R_System where AgentName in (“SMS_AD_SYSTEM_DISCOVERY_AGENT”) and DATEDIFF(day,AgentTime,GetDate())<7) |
Client Not Installed* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceId not in (select SMS_R_SYSTEM.ResourceID from SMS_R_System where SMS_R_System.Client = 1) and SMS_R_System.ResourceId in (select ResourceID from SMS_R_System where AgentName in (“SMS_AD_SYSTEM_DISCOVERY_AGENT”) and DATEDIFF(day,AgentTime,GetDate())<7) |
Client Not Installed and Error 112 No Disk Space during Client Push* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.Name in (Select InsStrValue from SMS_StatusMessage as stat left outer join SMS_StatMsgAttributes as att on stat.recordid = att.recordid left outer join SMS_StatMsgInsStrings as ins on stat.recordid = ins.recordid WHERE (COMPONENT=’SMS_CLIENT_CONFIG_MANAGER’) AND MessageID = 3014 AND Win32Error = 112 AND DATEDIFF(day,stat.Time,GetDate())<7) and SMS_R_System.ResourceId not in (select SMS_R_SYSTEM.ResourceID from SMS_R_System where SMS_R_System.Client = 1) |
Client Not Installed and Error 5 Access Denied during Client Push* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.Name in (Select InsStrValue from SMS_StatusMessage as stat left outer join SMS_StatMsgAttributes as att on stat.recordid = att.recordid left outer join SMS_StatMsgInsStrings as ins on stat.recordid = ins.recordid WHERE (COMPONENT=’SMS_CLIENT_CONFIG_MANAGER’) AND MessageID = 3014 AND Win32Error = 5 AND DATEDIFF(day,stat.Time,GetDate())<7) and SMS_R_System.ResourceId not in (select SMS_R_SYSTEM.ResourceID from SMS_R_System where SMS_R_System.Client = 1) |
PFE Remediation Script – Agent Not Installed | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceId not in (select ResourceID from SMS_R_System where ((DATEDIFF(day, SMS_R_SYSTEM.AgentTime, getdate()) <14) and AgentName = ‘PFE Remediation’)) |
PFE Remediation Script – Outdated Script* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.PFE_ScriptVer != ’14.7.3′ and ResourceID in ( select ResourceID from SMS_R_SYSTEM where DATEDIFF(day, SMS_R_SYSTEM.AgentTime, getdate()) <7 and AgentName = ‘PFE Remediation’) |
HINV Missing Information | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceID = SMS_R_System.ResourceId where SMS_G_System_COMPUTER_SYSTEM.Model is null and SMS_R_System.ResourceId in (select ResourceId from SMS_G_System_CH_ClientSummary Where ClientActiveStatus = 1) |
HINV Missing Information | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceId not in (select SMS_R_SYSTEM.ResourceID from SMS_R_System inner join SMS_G_System_OPERATING_SYSTEM on SMS_G_System_OPERATING_SYSTEM.ResourceId = SMS_R_System.ResourceId where SMS_G_System_OPERATING_SYSTEM.Caption like “%Windows%”) and SMS_R_System.ResourceId in (select ResourceId from SMS_G_System_CH_ClientSummary Where ClientActiveStatus = 1) |
Duplicate GUID* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceId in (select SMS_R_System.ResourceId from SMS_R_System inner join SMS_G_System_SYSTEM on SMS_G_System_SYSTEM.ResourceID = SMS_R_System.ResourceId where (SMS_R_System.Name != SMS_G_System_SYSTEM.Name and SMS_G_System_SYSTEM.Name is not null )) and SMS_R_System.ResourceId in (select SMS_R_SYSTEM.ResourceID from SMS_R_System inner join SMS_G_System_CH_ClientSummary on SMS_G_System_CH_ClientSummary.ResourceId = SMS_R_System.ResourceId where SMS_G_System_CH_ClientSummary.ClientActiveStatus = 1) |
HINV Last Scan Date Missing or Greater Than 30 Days* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceId not in (select SMS_R_System.ResourceId from SMS_R_System inner join SMS_G_System_WORKSTATION_STATUS on SMS_G_System_WORKSTATION_STATUS.ResourceId = SMS_R_System.ResourceId where DATEDIFF(day,SMS_G_System_WORKSTATION_STATUS.LastHardwareScan,GetDate())<30) and SMS_R_System.ResourceId in (select ResourceId from SMS_G_System_CH_ClientSummary Where ClientActiveStatus = 1) |
Software Updates Compliance Status Missing | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceId not in (select SMS_R_SYSTEM.ResourceID from sms_r_system inner join SMS_UpdateComplianceStatus on SMS_UpdateComplianceStatus.machineid = sms_r_system.resourceid Join SMS_Softwareupdate on SMS_Softwareupdate.CI_ID = SMS_UpdateComplianceStatus.CI_ID where SMS_UpdateComplianceStatus.Status = 0 or SMS_UpdateComplianceStatus.Status = 1 or SMS_UpdateComplianceStatus.Status = 2 or SMS_UpdateComplianceStatus.Status = 3) and SMS_R_System.ResourceId in (select SMS_R_SYSTEM.ResourceID from SMS_R_System inner join SMS_G_System_CH_ClientSummary on SMS_G_System_CH_ClientSummary.ResourceId = SMS_R_System.ResourceId where SMS_G_System_CH_ClientSummary.ClientActiveStatus = 1) |
HINV MIF Max File Size Exceeded | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.Name in (select SMS_StatusMessage.MachineName from SMS_StatusMessage LEFT OUTER JOIN SMS_StatMsgAttributes ON SMS_StatusMessage.RecordID = SMS_StatMsgAttributes.RecordID LEFT OUTER JOIN SMS_StatMsgInsStrings ON SMS_StatusMessage.RecordID = SMS_StatMsgInsStrings.RecordID where SMS_StatusMessage.MessageID = ’2719′ AND SMS_StatusMessage.Component = ‘SMS_INVENTORY_DATA_LOADER’ and DateDiff(dd,SMS_StatusMessage.Time, GetDate()) <7) |
SINV Incomplete Inventory | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceId not in (select SMS_R_SYSTEM.ResourceID from SMS_R_System inner join SMS_G_System_SoftwareFile on SMS_G_System_SoftwareFile.ResourceId = SMS_R_System.ResourceId where SMS_G_System_SoftwareFile.FileName = “notepad.exe”) and SMS_R_System.ResourceId in (select ResourceId from SMS_G_System_CH_ClientSummary Where ClientActiveStatus = 1) |
SINV Last Scan Date Missing or Greater Than 30 Days | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceId not in (select ResourceID from SMS_R_System inner join SMS_G_System_LastSoftwareScan on SMS_G_System_LastSoftwareScan.ResourceID = SMS_R_System.ResourceId where DATEDIFF(dd,SMS_G_System_LastSoftwareScan.LastScanDate,GetDate()) < 30) and SMS_R_System.ResourceId in (select ResourceId from SMS_G_System_CH_ClientSummary Where ClientActiveStatus = 1) |
Client Heartbeat Missing or Greater Than 14 days* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceId in (select ResourceID from SMS_R_System where (DATEDIFF(day, SMS_R_SYSTEM.AgentTime, getdate()) >14) and AgentName = ‘Heartbeat Discovery’) and SMS_R_System.ResourceId NOT in (select ResourceID from SMS_R_System where (DATEDIFF(day, SMS_R_SYSTEM.AgentTime, getdate()) <14) and AgentName = ‘Heartbeat Discovery’) and SMS_R_System.ResourceId in (select ResourceId from SMS_G_System_CH_ClientSummary Where ClientActiveStatus = 1) |
Client Activity = Inactive* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CH_ClientSummary on SMS_G_System_CH_ClientSummary.ResourceId = SMS_R_System.ResourceId where SMS_G_System_CH_ClientSummary.ClientActiveStatus = 0 |
CM Client Version Outdated* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ClientVersion < “5.00.8239.1000″ and SMS_R_System.ResourceId in (select SMS_R_SYSTEM.ResourceID from SMS_R_System inner join SMS_G_System_CH_ClientSummary on SMS_G_System_CH_ClientSummary.ResourceId = SMS_R_System.ResourceId where SMS_G_System_CH_ClientSummary.ClientActiveStatus = 1) |
Clients Not Receiving Policy (Invalid Signature) | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_SYSTEM.SMSUniqueIdentifier in (select instr.insstrvalue from SMS_StatusMessage as sm join SMS_StatInsStr as instr on sm.recordid=instr.recordid where sm.messageid = 5448 and instr.insstrvalue like ‘GUID%’ and DateDiff(dd,sm.Time, GetDate()) < 7) |
CI – DP Latency Threshold Exceeded | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – DP Latency Threshold” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – CCM Cache Size Configured Incorrectly | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – CCM Cache Size” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – CCMEVAL – No Recent Execution | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – CCMEVAL Recent Execution” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
Unsupported Domain or Workgroup | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ResourceDomainORWorkgroup not in (“Energy”,”RegencyGas”,”SECHOU”,”ETC”,”PVR”,”EagleRock”,”PVRPartners”) and SMS_R_System.ResourceId in (select ResourceID from SMS_R_System where ((DATEDIFF(day, SMS_R_SYSTEM.AgentTime, getdate()) <=7) and AgentName = “Heartbeat Discovery”)) |
CI – Admin$ Share is Not Accessible | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – Admin$ Is Accessible” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – BITS Throttling – Not Configured Properly | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId inner join SMS_CI_ComplianceHistory on SMS_CI_ComplianceHistory.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – BITS Throttling Policy” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_CI_ComplianceHistory.ComplianceStartDate,GetDate())<=7 |
CI – Group Policy Processing Issues | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – GPO Processing Check” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – Pending Reboot (Pending File Rename Operation)* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – No Pending Reboot Due To File Rename Operation” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – Pending Reboot (Software Updates)* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – No Pending Reboot Due To Software Updates” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – Windows Update Scan Errors* | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – Windows Update Scan” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – Service Status – Microsoft Anti-Virus Not Running | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – Service Status – Microsoft Anti-Virus Running” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-CompliantCustomerSpecific” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – Bitlocker Encryption Not Enabled on C: | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – BitLocker Encryption Status” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – WSC – Anti-Spyware State Not Recommended | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – WSC – Anti-Spyware State” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – WSC – Anti-Virus State Not Recommended | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – WSC – Anti-Virus State” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – WSC – Auto-Update Settings Not Recommended | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – WSC – Auto-Update Settings” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – WSC – Firewall State Not Recommended | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – WSC – Firewall State” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – WSC – Internet Settings Not Recommended | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – WSC – Internet Settings” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – WSC – User Account Control (UAC) Settings Not Recommended | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – WSC – User Account Control (UAC) Settings” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
CI – WSC – Windows Security Center Service State Not Running | select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_CI_ComplianceState on SMS_G_System_CI_ComplianceState.ResourceID = SMS_R_System.ResourceId where SMS_G_System_CI_ComplianceState.LocalizedDisplayName = “PFE – WSC – Windows Security Center Service (WSC) State” and SMS_G_System_CI_ComplianceState.ComplianceStateName = “Non-Compliant” and DATEDIFF(day,SMS_G_System_CI_ComplianceState.LastComplianceMessageTime,GetDate())<=7 |
Windows 10 deployment and management lab kit
Microsoft released new Windows 10 Deployment and Management Lab Kit includes everything you need to review the new in-place upgrade option plus traditional deployment methods and other management tools
https://technet.microsoft.com/en-us/windows/mt604890.aspx
Note:——
*Lab environment requires 32 GB of available memory and 300 GB of free disk space. Lab expires April 15, 2016.
Update 1602 for Technical Preview
RDP Enable using PSEXEC
psexec \\XXXXXXXXXX reg add “hklm\system\currentcontrolset\control\terminal server” /f /v fDenyTSConnections /t REG_DWORD /d 0
//////////******* List of Views /Tables with fields**********////////////
////////////////****************************** List of Tables with fields************************///////////////////////////
SELECT T.NAME AS [TABLE NAME], C.NAME AS [COLUMN NAME], P.NAME AS [DATA TYPE], P.MAX_LENGTH AS[SIZE], CAST(P.PRECISION AS VARCHAR) +’/’+ CAST(P.SCALE AS VARCHAR) AS [PRECISION/SCALE] FROM SYS.OBJECTS AS T JOIN SYS.COLUMNS AS C ON T.OBJECT_ID=C.OBJECT_ID JOIN SYS.TYPES AS P ON C.SYSTEM_TYPE_ID=P.SYSTEM_TYPE_ID WHERE T.TYPE_DESC=’USER_TABLE’;
////////////////****************************** List of Views with fields************************///////////////////////////
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_PRECISION_RADIX, NUMERIC_SCALE, DATETIME_PRECISION FROM INFORMATION_SCHEMA.COLUMNS
Pull Distribution Points with Source Distribution Points SQL Query
SELECT DISTINCT
dbo.v_DistributionPoints.ServerName AS [Source DP for Pull], dbo.v_DistributionPoints.IsPeerDP, dbo.v_DistributionPoints.IsPullDP,
dbo.vPullDPFullMap.PullDPNALPath AS [All Types of DP List], dbo.v_DistributionPoints.IsPXE, dbo.v_DistributionPoints.Description
FROM dbo.vPullDPFullMap INNER JOIN
dbo.v_DistributionPoints ON dbo.vPullDPFullMap.SourceDPNALPath = dbo.v_DistributionPoints.NALPath
Software Updates Installed using SCCM or Manually
SELECT sys.Name0,ui.BulletinID, ui.ArticleID,ui.Title,
CASE when (ucs.Status=2 and ui.IsDeployed=0 )then ‘Required_General’
when (ucs.Status=2 and ui.IsDeployed=1 )then ‘Required_ITICSDeploy’
WHEN (UCS.Status=3 and ui.IsDeployed=1 ) then ‘Installed_SCCM’
WHEN (UCS.Status=3 and ui.IsDeployed=0 ) then ‘Installed_Manual’
when UCS.Status=0 then ‘Unknown’ end as ‘Status’, case WHEN ui.severity=10 THEN ‘Critical’
WHEN ui.severity=8 THEN ‘Important’
WHEN ui.severity=6 THEN ‘Moderate’
WHEN ui.severity=2 THEN ‘Low’ WHEN ui.severity=0 THEN ‘AddOn’ end as ‘Severity’
FROM v_R_System sys
INNER JOIN v_UpdateComplianceStatus UCS ON sys.ResourceID = ucs.ResourceID
INNER JOIN v_UpdateInfo UI ON UCS.CI_ID = UI.CI_ID
WHERE –UI.IsDeployed=1 and
sys.Netbios_Name0=’computer1′
ORDER BY Status
SCCM 2012: List of Public Microsoft Support Knowledge Base Articles
List of Users to add in a SCCM User Collection
select SMS_R_USER.ResourceID,SMS_R_USER.ResourceType,SMS_R_USER.Name,SMS_R_USER.UniqueUserName,SMS_R_USER.WindowsNTDomain from SMS_R_User where SMS_R_User.UserName in (‘User1′,’User2′)
Basic USMT Understanding with example of windows 7 to Windows 10 user profile migration
USMT is one of the Tool from ADK (Windows Assessment and Deployment Kit )
User State Migration Tool (USMT) is a tool that can be used to migrate user state, data and settings as part of a image build or outside of image. It will process to transfer mapped drives, favorites, and other settings listed below to a separate computer in hopes that it would help with machine refreshes and replacements.
With this USMT tool we are able to copy and restore the following:
- Custom Map drives
- STARTMENU configuration
- QUICK LAUNCH settings
- DESKTOP settings
- Printers
- User Accounts
- PERSONAL
- MYPICTURES
- FAVORITES
- MYVIDEO
- MYMUSIC
Files with the following extensions:we can do customization if we want
- .qdf, .qsd, .qel, .qph, .doc*, .dot*, .rtf, .mcw, .wps, .scd, .wri, .wpd, .xl*, .csv, .iqy, .dqy, .oqy, .rqy, .wk*, .wq1, .slk, .dif, .ppt*, .pps*, .pot*, .sh3, .ch3, .pre, .ppa, .txt, .pst, .one*, .vl*, .vsd, .mpp, .or6, .accdb, .mdb, .pub
Limitation of USMT ,Which it wont migrate following things :—
- Files tagged with both the hidden and system attributes.
- Files and folders on removable drives,
- Data from the %WINDIR%, %PROGRAMFILES%, %PROGRAMDATA% folders.
- ACLS for files in folders outside the user profile.
- Local attached printers won’t migrate
How USMT will work :
USMT will work based on XML Files. USMT Package will have XML Files.Like MigApp.XML , MigUser.XML , MigDocs.XML , Config.xml etc. Each and every XML file has specific components to migrate. If you want to read the XML file user the XML Editor for easy to understand.
I haven’t tried but you can also use the USMT GUI editor check out this .
so if you want to customize the XML file always better to create new XML file rather than editing the default XML file
in my example I’m attaching my XML file.
My requirement is user profile only requires to restore .below are the points in detailed
- it should not restore any documents under C:\Drive (or any other folders under C drive).
- User desktop documents and user profile settings,shortcuts,Pin items,desktop wallpaper , favorites , My pictures,my documents,etc
- Also under C:\temp\Printer\any files it should restore
download sample XML files it has my sample custom files Custom2.xml and Migration.xml you needs to call at Capture User Files and Settings in Task sequence and Restore User State
Sample SCCM Task Sequence :–
Assuming you already have the USMT package in place in SCCM console
Here Profile Capturing /Storing will be in 2 Ways
- SMP (State Migration Point) : Its a role from SCCM. its kind of share location where we can use for profile storage
Advantages /Disadvantages : —
- We should have enough space to store the user data . If your concern about space check out this to get some idea how much space you may requires Collecting USMT Estimates using ConfigMgr
- With SMP It has it own mechanism for deleting the aged data or maintenance task
- Also data will be encrypted and we can’t able to see the files. It will be stored in .MIG format
- It will slow process to compare to Hard-Link process . Since data will be stored in remote location. Speed of the process will depends on the bandwidth
- Local store / Wipe Mode (Hard-link migration) - It will create Links in the Sectors of inside the Hard disk and It will Wipe the HardDrive. When It restore calls.
Advantages /Disadvantages : —
- By using the linking mechanism from sectors it will restore the user data – So here We can’t format 100% of the hard drive
- Since data will be stored under local hard drive.it will be faster to compare to SMP
Summary of steps need to perform to migrate the StandAlone user profile [SMP]. :—
SCOPE :User profile migration from Windows7 to Windows 10/other machine as your wish
- USMT Package should be ready with above Xml Files. Paste above XMl files under USMT folders
- SMP Role should be in place
- relate the old and new computers in Computer Association as shown
- create a task sequence for capture in above case Task sequence 1
- create a task sequence for restore in above case Task sequence 2
- Create a Collection called ” Capture ” and add the machine windows 7
- Deploy the Task sequence 1 on ” Capture “Collection. Make sure it should get success
- Create a Collection called ” Restore ” and add the machine windows 10
- Deploy the Task sequence 2 on ” Restore ” Collection. Make sure it should get success
Above steps will explain in details in below :—
I have 2 machines windows 7 and Windows 10 / Or any other version windows7/8.1 etc
Now I want to transfer my user profile data from Windows7 machine to windows 10 machine
For this, we need 2 Task sequences with below steps and Computer Association
First we need to co-relate the machine relation with help of Computer Association.
Here you can add specific user or all user etc settings
1 Task sequence — > For user profile Capturing – Here “Capture USMT “ Task Sequence Set will be use full as showing in below screenshots. This Task sequence we will be run on Windows 7 machine
2. Task Sequence –> To restore user profile.Here “Restore” Task Sequence Set will be use full as showing in below screenshots. This Task sequence we will be run on Windows 10 machine
Task sequence 1 : ScanState [ For Capturing the User profile settings]
Task sequence 2 : LoadState [ For Restoring the User profile settings]
TrobleShooting Steps and Logs info :—
- You may face the issues in either capturing or Restoring stage which are related to USMT
- At the time of running the task sequence it create a Folder “C:\_SMSTaskSequence” and download the USMT Package inside it and also it will create the folder “SMSTSLog”under C:\Windows\CCM\Logs\SMSTSLog
- SMSTSLog folder contains the log at the time of running the task sequence .once task sequence completes it will move the logs to under CCM folder C:\Windows\CCM\Logs
For capturing the user data below logs will help you
- SMSTS.log : General Task sequence execution info
- scanstate.log – scans all user profiles and what files its scanned according to the XML defined
- scanstateprogress.log : How much Percentage it completes
For restoring the user data below logs will help you
- SMSTS.log : General Task sequence execution info
- loadstate.log- Loads all user profiles and what files it should restore according to the XML
- loadstateprogress.log : How much Percentage it restored s it will shows
Known Issues: —
- If you’re running multiple time on same machine irrespective of result . so might get certificate error.
- Just delete the certificates from the locations [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\SMS\Certificates] It will resolve the issue
Failed to decrypt state encryption key
sometime at the time creating the computer association it got sucked , hanged. Please remove it and recreate the computer association will fix above error
Most of the cases USMT will failed due to Invalid User Mapping or duplicate SID issue on Source machine while capturing.
This issue will occur due to domain migration when they are migrating the user profile with ADMT (Active Directory Migration Tool) They won’t delete the old domain SID’s
check out for more info http://networksteve.com/?p=5022
Please find the script which it will remove the Specified SID user profile SIDREMOVAL.vbs .It will takes the Registry back and removes the user profile if the user profile has duplicate SID.
Specific application From specific Collection ID
SELECT DISTINCT c.Name0 AS [Machine Name] , a.DisplayName0 AS [software name], a.Version0 AS [Version], dbo.v_FullCollectionMembership.CollectionID
FROM dbo.v_Add_Remove_Programs AS a INNER JOIN
dbo.v_R_System AS c ON a.ResourceID = c.ResourceID INNER JOIN
dbo.v_FullCollectionMembership ON c.ResourceID = dbo.v_FullCollectionMembership.ResourceID
WHERE (a.DisplayName0 LIKE ‘JAVA%’) AND (dbo.v_FullCollectionMembership.CollectionID IN (‘XXXXX’))
How to find SCCM 2012 collection location
select c.SiteID as ‘Collection ID’,c.CollectionName,f.Name
as ‘Folder Name’ from vCollections c
inner join FolderMembers fm on fm.InstanceKey=c.SiteID
inner join folders f on f.ContainerNodeID=fm.ContainerNodeID
Boundaries With Count of Devices
SELECT
IP_Subnets0 AS ‘Subnets Detected’,
vSMS_Boundary.Value AS ‘Sorted:Boundary Values’,
COUNT(v_RA_System_IPSubnets.ResourceID)AS ‘Count of Devices’,
vSMS_Boundary.DisplayName,
vSMS_Boundary.CreatedOn,
vSMS_Boundary.ModifiedOn
FROM v_RA_System_IPSubnets
Full Join vSMS_Boundary on vSMS_Boundary.Value =
v_RA_System_IPSubnets.IP_Subnets0
Where (v_RA_System_IPSubnets.IP_Subnets0 like ’172.1[6-9].%’ or
v_RA_System_IPSubnets.IP_Subnets0 like ’172.2[0-9].%’ or
v_RA_System_IPSubnets.IP_Subnets0 like ’172.3[0-1].%’) or
(vSMS_Boundary.Value like ’172.1[6-9].%’ or
vSMS_Boundary.Value like ’172.2[0-9].%’ or
vSMS_Boundary.Value like ’172.3[0-1].%’)or
v_RA_System_IPSubnets.IP_Subnets0 like ’10.%’ or
v_RA_System_IPSubnets.IP_Subnets0 like ’192.168.%’ or
vSMS_Boundary.Value like ’10.%’ or
vSMS_Boundary.Value like ’192.168.%’
Group By vSMS_Boundary.Value,
v_RA_System_IPSubnets.IP_Subnets0,vSMS_Boundary.DisplayName,vSMS_Boundary.CreatedOn,vSMS_Boundary.ModifiedOn
Order By [Sorted:Boundary Values]
My Scripts
Netsh firewall set opmode disable
sc config Browser start= auto
sc start Browser
sc config lanmanserver start= auto
sc start lanmanserver
sc config lanmanworkstation start= auto
sc start lanmanworkstation
sc config RemoteRegistry start= auto
sc start RemoteRegistry
sc config wuauserv start= auto
sc start wuauserv
sc config EventSystem start= auto
sc start EventSystem
sc config winmgmt start= auto
sc start winmgmt
sc config RpcSs start= auto
sc start RpcSs
sc config BITS start= auto
sc start BITS
net start Browser
sc config Schedule start= auto
sc start Schedule
sc config MSIServer start= auto
sc start MSIServer
********************************
Uninstall “Microsoft Office Enterprise 2007″***********
MsiExec.exe /X{90120000-0030-0000-0000-0000000FF1CE} /qn
*******Office-Standard-Edition-2003*******
MsiExec.Exe /x {90120409-6000-11D3-8CFE-0150048383C9} /qn
******Office-Professional-Edition-2003*********
MsiExec.Exe /x {90110409-6000-11D3-8CFE-0150048383C9} /qn
*****Microsoft-Office-2010**************
MsiExec.exe /X{95140000-0070-0000-0000-0000000FF1CE} /qn
********”Microsoft Office Standard 2007″ Uninstall**********
MsiExec.exe /X{90120000-0012-0000-0000-0000000FF1CE} /qn
*******”Microsoft Office Professional Plus 2007″ Uninstall*******
MsiExec.exe /X{90120000-0011-0000-0000-0000000FF1CE} /qn
***********************
WithNAP FlashMessage!!! name.VBS
dim naptime, objDOS
naptime = 10
set objDOS = CreateObject (“WScript.Shell”)
objDOS.Popup “Desired Text need to be type here.” , naptime, “Information”, 64
*************
Without NAP FlashMessage!!! name.VBS
MsgBox(“Desired Text need to be type here.”)
************************
MS Office 2003 Removal Script . VBS
**
‘=======================================================================
================================
‘ Name: OffScrub03.vbs
‘ Author: Microsoft Customer Support Services
‘ Copyright (c) 2010, Microsoft Corporation
‘ Script to remove (scrub) Office 2003 products
‘=======================================================================
================================
Option Explicit
Const VERSION = “1.21″
Const HKCR = &H80000000
Const HKCU = &H80000001
Const HKLM = &H80000002
Const HKU = &H80000003
Const FOR_WRITING = 2
Const PRODLEN = 28
Const OFFICE_2003 = “6000-11D3-8CFE-0150048383C9}”
Const COMPPERMANENT = “00000000000000000000000000000000″
Const UNCOMPRESSED = 38
Const COMPRESSED = 32
Const REG_ARP = “SOFTWARE\Microsoft\Windows\CurrentVersion
\Uninstall\”
Const DELIVERY = “SOFTWARE\Microsoft\Office\11.0\Delivery\”
‘=======================================================================
================================
Dim oFso, oMsi, oReg, oWShell, oWmiLocal
Dim ComputerItem, Item, LogStream, TmpKey
Dim arrInstalledSKUs
Dim arrDeleteFiles, arrDeleteFolders, arrMseFolders
Dim dicKeepProd, dicKeepLis, dicApps, dicKeepFolder, dicDelRegKey
Dim dicInstalledSku, dicRemoveSku, dicKeepSku
Dim f64
Dim sErr, sTmp, sSkuInstalledList, sSkuRemoveList, sDefault, sWinDir,
sMode
Dim sAppData, sTemp, sScrubDir, sProgramFiles, sProgramFilesX86,
sCommonProgramFiles, sAllusersProfile
Dim sOInstallRoot
‘=======================================================================
================================
‘Main
‘=======================================================================
================================
‘Configure defaults
Dim sLogDir : sLogDir = “”
Dim sMoveMessage: sMoveMessage = “”
Dim fRemoveOSE : fRemoveOSE = False
Dim fRemoveAll : fRemoveAll = False
Dim fKeepUser : fKeepUser = True ‘Default to keep per user
settings
Dim fForceKeepUser : fForceKeepUser = False ‘Extended user settings
behavior
Dim fSkipSD : fSkipSD = False ‘Default to not Skip the Shortcut
Detection
Dim fDetectOnly : fDetectOnly = False
Dim fQuiet : fQuiet = False
‘CAUTION! -> “fForce” will kill running applications which can result in
data loss! “fForce” will kill running applications which can result in
data loss! 0
Next
If f64 Then sProgramFilesX86 = oWShell.ExpandEnvironmentStrings
(“%programfiles(x86)%”)
‘Call the command line parser
ParseCmdLine
If Not CheckRegPermissions Then
Log vbCrLf & “Insufficient registry access permissions – exiting”
wscript.quit
End If
‘Get Office Install Folder
If NOT RegReadValue(HKLM,”SOFTWARE\Microsoft\Office\11.0\Common
\InstallRoot”,”Path”,sOInstallRoot,”REG_SZ”) Then
sOInstallRoot = sProgramFiles & “\Microsoft Office\Office11″
End If
‘Ensure integrity of WI metadata which could fail used APIs otherwise
EnsureValidWIMetadata HKCU,”Software\Classes\Installer
\Products”,COMPRESSED
EnsureValidWIMetadata HKCR,”Installer\Products”,COMPRESSED
EnsureValidWIMetadata HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion
\Installer\UserData\S-1-5-18\Products”,COMPRESSED
EnsureValidWIMetadata HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion
\Installer\UserData\S-1-5-18\Components”,COMPRESSED
EnsureValidWIMetadata HKCR,”Installer\Components”,COMPRESSED
‘——————-
‘Stage # 0 – Basics |
‘——————-
‘Build a list with installed/registered Office 2003 products
sTmp = “Stage # 0 ” & chr(34) & “Basics” & chr(34) & ” (” & Time & “)”
Log vbCrLf & sTmp & vbCrLf & String(Len(sTmp),”=”) & vbCrLf
FindInstalledO11Products
If dicInstalledSku.Count > 0 Then Log “Found registered product(s): ” &
Join(RemoveDuplicates(dicInstalledSku.Items),”,”) &vbCrLf
‘Validate the list of products we got from the command line if
applicable
ValidateRemoveSkuList
‘Check which parts of the local installation source has to remain
CheckLIS
‘Log detection results
If dicRemoveSku.Count > 0 Then Log “Product(s) to be removed: ” & Join
(RemoveDuplicates(dicRemoveSku.Items),”,”)
sMode = “Selected Office 2003 products”
If NOT dicRemoveSku.Count > 0 Then sMode = “Orphaned Office 2003
products”
If fRemoveAll Then sMode = “All Office 2003 products”
Log “Final removal mode: ” & sMode & vbCrLf
Log “Remove OSE service: ” & fRemoveOSE &vbCrLf
‘Log preview mode if applicable
If fDetectOnly Then Log
“***********************************************************************
**”
If fDetectOnly Then Log “* PREVIEW MODE
*”
If fDetectOnly Then Log “* All uninstall and delete operations will only
be logged not executed! *”
If fDetectOnly Then Log
“***********************************************************************
**” & vbCrLf
‘Cache .msi files
If dicRemoveSku.Count > 0 Then CacheMsiFiles
‘——————————–
‘Stage # 1 – Component Detection |
‘——————————–
sTmp = “Stage # 1 ” & chr(34) & “Component Detection” & chr(34) & ” (” &
Time & “)”
Log vbCrLf & sTmp & vbCrLf & String(Len(sTmp),”=”) & vbCrLf
If Not fBypass_Stage1 Then
‘Build a list with files which are installed/registered to a product
that’s going to be removed
Log “Prepare for CleanUp stages.”
Log “Identifying removable elements. This can take several minutes.”
ScanComponents
Else
Log “Skipping Component Detection because bypass was requested.”
End If
‘End all running Office applications
If fForce OR fQuiet Then CloseOfficeApps
‘————————
‘Stage # 2 – Msiexec.exe |
‘————————
sTmp = “Stage # 2 ” & chr(34) & “Msiexec.exe” & chr(34) & ” (” & Time &
“)”
Log vbCrLf & sTmp & vbCrLf & String(Len(sTmp),”=”) & vbCrLf
If Not fBypass_Stage2 Then
MsiexecRemoval
Else
Log “Skipping Msiexec.exe because bypass was requested.”
End If
‘——————–
‘Stage # 3 – CleanUp |
‘——————–
‘Removal of files and registry settings
sTmp = “Stage # 3 ” & chr(34) & “CleanUp” & chr(34) & ” (” & Time & “)”
Log vbCrLf & sTmp & vbCrLf & String(Len(sTmp),”=”) & vbCrLf
If Not fBypass_Stage3 Then
‘Office Source Engine
If fRemoveOSE Then RemoveOSE
‘Local Installation Source (MSOCache)
WipeLIS
‘Obsolete files
If fRemoveAll Then
FileWipeAll
Else
FileWipeIndividual
End If
‘Empty Folders
DeleteEmptyFolders
‘Restore Explorer if needed
If fForce Then RestoreExplorer
‘Registry data
RegWipe
‘Wipe orphaned files from Windows Installer cache
MsiClearOrphanedFiles
‘Temporary .msi files in scrubcache
DeleteMsiScrubCache
‘Temporary files from file move operations
DelScrubTmp
Else
Log “Skipping CleanUp because bypass was requested.”
End If
If Not sMoveMessage = “” Then Log vbCrLf & “Please remove this folder
after next reboot: ” & sMoveMessage
‘THE END
Log vbCrLf & “End removal: ” & Now & vbCrLf
Log vbCrLf & “For detailed logging please refer to the log in folder ”
&chr(34)&sScrubDir&chr(34)&vbCrLf
If fRebootRequired Then Log vbCrLf & “A restart is required to complete
the operation!”
‘=======================================================================
================================
‘=======================================================================
================================
‘Stage 0 – 4 Subroutines
‘=======================================================================
================================
‘Office 2003 products are listed with their ProductCode in the
“Uninstall” key
Sub FindInstalledO11Products
Dim ArpItem, prod, Item
Dim sConfigName
Dim arrKeys
If dicInstalledSku.Count > 0 Then Exit Sub ‘Already done from
InputBox prompt
‘Query msi to get a list of Office 2003 products
For Each prod in oMsi.Products
If UCase(Right(prod,PRODLEN)) = OFFICE_2003 Then
sConfigName = “”
sConfigName = UCase(GetProductID(Mid(prod,4,2)))
If Not dicInstalledSku.Exists(prod) Then dicInstalledSku.Add
UCase(prod),sConfigName
End If ‘OFFICE_2003
Next ‘prod
‘Locate Office 2003 products from ARP
If RegEnumKey(HKLM,REG_ARP,arrKeys) Then
For Each ArpItem in arrKeys
If UCase(Right(ArpItem,PRODLEN)) = OFFICE_2003 Then
sConfigName = “”
sConfigName = UCase(GetProductID(Mid(ArpItem,4,2)))
If Not dicInstalledSku.Exists(ArpItem) Then
dicInstalledSku.Add UCase(ArpItem),sConfigName
End If
Next ‘ArpItem
End If ‘RegEnumKey
End Sub ‘FindInstalledO11Products
‘=======================================================================
================================
‘Create clean list of Products to remove.
‘Strip off bad & empty contents
Sub ValidateRemoveSkuList
Dim Sku, Key
Dim arrRemoveSKUs
If fRemoveAll Then
‘Remove all mode
For Each Key in dicInstalledSku.Keys
Select Case dicInstalledSku.Item(Key)
‘Override default to remove Project server
Case “PRJSRV”
dicKeepProd.Add Key,dicInstalledSku.Item(Key)
fRemoveAll = False
Case Else
dicRemoveSku.Add Key,dicInstalledSku.Item(Key)
End Select
Next ‘Key
Else
‘Remove individual products mode
‘Ensure to have a string with no unexpected contents
sSkuRemoveList = Replace(sSkuRemoveList,”;”,”,”)
sSkuRemoveList = Replace(sSkuRemoveList,” “,””)
sSkuRemoveList = Replace(sSkuRemoveList,Chr(34),””)
While InStr(sSkuRemoveList,”,,”)>0
sSkuRemoveList = Replace(sSkuRemoveList,”,,”,”,”)
Wend
‘Prepare ‘remove’ and ‘keep’ dictionaries to determine what has
to be removed
‘Initial pre-fill of ‘keep’ dic
For Each Key in dicInstalledSku.Keys
dicKeepProd.Add Key,dicInstalledSku.Item(Key)
Next ‘Key
‘Determine contents of keep and remove dic
arrRemoveSKUs = Split(UCase(sSkuRemoveList),”,”)
For Each Sku in arrRemoveSKUs
If Sku = “OSE” Then fRemoveOse = True
If dicKeepProd.Exists(Sku) Then
‘A productcode has been passed in
‘remove the item from the keep dic
dicKeepProd.Remove(Sku)
‘Now add it to the remove dic
dicRemoveSku.Add Sku,Sku
End If
‘Check the Sku based entries
For Each Key in dicKeepProd.Keys
If dicKeepProd.Item(Key) = Sku Then
dicRemoveSku.Add Sku,Sku
dicKeepProd.Remove(Key)
End If
Next ‘Key
Next ‘Sku
If NOT dicKeepProd.Count > 0 Then fRemoveAll = True
End If ‘fRemoveAll
If fRemoveAll OR fRemoveOSE Then CheckRemoveOSE
End Sub ‘ValidateRemoveSkuList
‘=======================================================================
================================
‘Check if OSE service can be scrubbed
Sub CheckRemoveOSE
Dim Product,Service,Services
Dim sOsePath
‘Keep OSE if a later version than 11.x is found
Set Services = oWmiLocal.Execquery(“Select * From Win32_Service
Where Name=’OSE’”)
For Each Service in Services
sOsePath = Replace(Service.PathName,chr(34),””)
If oFso.FileExists(sOsePath) Then
If CInt(Left(oFso.GetFileVersion(sOsePath),2)) > 11 Then
LogOnly “Disallowing OSE removal. OSE version found: ” &
oFso.GetFileVersion(sOsePath)
fRemoveOse = False
Exit Sub
End If
End If
Next ‘Service
fRemoveOSE = True
End Sub ‘CheckRemoveOSE
‘=======================================================================
================================
‘Cache .msi files for products that will be removed in case they are
needed for later file detection
Sub CacheMsiFiles
Dim Product
Dim sMsiFile
‘Non critical routine for failures.
‘Errors will be logged but must not fail the execution
On Error Resume Next
Log ” Cache .msi files to temporary Scrub folder”
‘Cache the files
For Each Product in oMsi.Products
‘Ensure valid GUID length
If Len(Product) = 38 Then
If (Right(Product,PRODLEN) = OFFICE_2003) AND (fRemoveAll OR
CheckDelete(Product))Then
CheckError “CacheMsiFiles”
sMsiFile = oMsi.ProductInfo(Product,”LocalPackage”) :
CheckError “CacheMsiFiles”
LogOnly ” – ” & Product & “.msi”
If oFso.FileExists(sMsiFile) Then oFso.CopyFile
sMsiFile,sScrubDir & “\” & Product & “.msi”,True
CheckError “CacheMsiFiles”
End If ‘OFFICE_2003
End If ’38
Next ‘Product
Err.Clear
End Sub ‘CacheMsiFiles
‘=======================================================================
================================
‘Build a list of all files that will be deleted
Sub ScanComponents
Const MSIOPENDATABASEREADONLY = 0
Dim FileList, ComponentID, CompClient, Record, qView, MsiDb
Dim sQuery, sSubKeyName, sPath, sFile, sMsiFile, sCompClient,
sComponent
Dim fRemoveComponent
Dim i, iProgress, iCompCnt
Dim dicFLError, oDic, oFolderDic
‘Logfile
Set FileList = oFso.OpenTextFile(sScrubDir &
“\FileList.txt”,FOR_WRITING,True,True)
‘FileListError dic
Set dicFLError = CreateObject(“Scripting.Dictionary”)
Set oDic = CreateObject(“Scripting.Dictionary”)
Set oFolderDic = CreateObject(“Scripting.Dictionary”)
‘Prevent that API errors fail script execution
On Error Resume Next
iCompCnt = oMsi.Components.Count
If NOT Err = 0 Then
‘API failure
Log “Error during components detection. Cannot complete this
task.”
Err.Clear
Exit Sub
End If
‘Ensure to not divide by zero
If iCompCnt = 0 Then iCompCnt = 1
‘Enum all Components
For Each ComponentID In oMsi.Components
‘Progress bar
i = i + 1
If iProgress 0 Then sFile = Mid
(sFile,InStr(sFile,”|”)+1,Len(sFile))
If Len(sFile)>4 Then
If LCase(Right(sFile,4))=”.exe” Then
If NOT dicApps.Exists(LCase(sFile)) Then
dicApps.Add LCase(sFile),LCase(sPath & “\” & sFile)
End If
End If
sFile = sPath & “\” & sFile
If Not oDic.Exists(sFile) Then
oDic.Add sFile,sFile
FileList.WriteLine sFile
End If
Set Record = qView.Fetch()
Loop
Set Record = Nothing
qView.Close
Set qView = Nothing
Else
If NOT dicFLError.Exists(“Error: Could not read from
.msi file: “&sMsiFile) Then _
dicFLError.Add “Error: Could not read from .msi
file: “&sMsiFile, ComponentID
Err.Clear
End If ‘Err = 0
End If ‘FileExists(sPath)
Else
‘Add the path to the ‘KeepFolder’ dictionary
Err.Clear
For Each CompClient In oMsi.ComponentClients(ComponentID)
‘Get the component path
sPath = “” : sPath = LCase(oMsi.ComponentPath
(CompClient,ComponentID))
If oFso.FileExists(sPath) Then
sPath = LCase(oFso.GetFile(sPath).ParentFolder)
If Not dicKeepFolder.Exists(sPath) Then
AddKeepFolder sPath
End If
Next ‘CompClient
End If ‘fRemoveComponent
Next ‘ComponentID
Err.Clear
On Error Goto 0
Log ” Done”
If dicFLError.Count > 0 Then LogOnly Join(dicFLError.Keys,vbCrLf)
If Not oFolderDic.Count = 0 Then arrDeleteFolders = oFolderDic.Keys
Else Set arrDeleteFolders = Nothing
If Not oDic.Count = 0 Then arrDeleteFiles = oDic.Keys Else Set
arrDeleteFiles = Nothing
End Sub ‘ScanComponents
‘=======================================================================
================================
‘Invoke msiexec to remove individual .MSI packages
Sub MsiexecRemoval
Const MSIINSTALLSTATEABSENT = 2
Const MSIUILEVELNONE = 2
Const MSIUILEVELBASIC = 3 ‘Simple progress and error handling.
Const MSIUILEVELHIDECANCEL = 32 ‘ shows progress dialog boxes but
does not display a Cancel button
Const MSIUILEVELPROGRESSONLY = 64 ‘displays progress dialog boxes
but does not display any modal dialog boxes or error dialog boxes.
Dim Product
Dim i
Dim sCmd, sReturn
‘Check registered products
‘Removal can only happen for per machine and current user context ->
use Installer.Products object
i = 0
For Each Product in oMsi.Products
If (Right(UCase(Product),PRODLEN) = OFFICE_2003) Then
If fRemoveAll OR CheckDelete(Product)Then
i = i + 1
Log ” Removing product ” & Product
sCmd = “msiexec.exe /x” & Product & ”
REBOOT=ReallySuppress”
If fQuiet Then
sCmd = sCmd & ” /q”
Else
sCmd = sCmd & ” /qb-”
End If
sCmd = sCmd & ” /l*v+ “&chr(34)
&sLogDir&”\Uninstall_”&Product&”.log”&chr(34)
If NOT fDetectOnly Then
Log ” – Calling msiexec with ‘”&sCmd&”‘”
‘Execute the patch uninstall
sReturn = oWShell.Run(sCmd, 0, True)
Log ” – msiexec returned: ” & SetupRetVal(sReturn) &
” (” & sReturn & “)” & vbCrLf
fRebootRequired = fRebootRequired OR (sReturn =
“3010″)
Else
Log ” -> Removal suppressed in preview mode.
Command: “&sCmd
End If
End If
End If ‘OFFICE_2003
Next ‘Product
If i = 0 Then Log “Nothing to remove for msiexec”
End Sub ‘MsiexecRemoval
‘=======================================================================
================================
‘Remove the OSE (Office Source Engine) service
Sub RemoveOSE
On Error Resume Next
Log ” OSE CleanUp”
DeleteService “ose”
‘Delete the folder
DeleteFolder sCommonProgramFiles & “\Microsoft Shared\Source Engine”
‘Delete the registration
RegDeleteKey HKLM,”SYSTEM\CurrentControlSet\Services\ose”
End Sub ‘RemoveOSE
‘=======================================================================
================================
‘Identify which parts of the LIS (MSOCache) will not be removed
Sub CheckLIS
Dim Prod
Dim sDownloadCode
If NOT dicKeepProd.Count > 0 Then Exit Sub
‘Loop all products that remain installed
For Each Prod in dicKeepProd.Keys
If RegReadValue
(HKLM,DELIVERY&Prod,”DownloadCode”,sDownloadCode,”REG_SZ”) Then
If dicKeepLis.Exists(UCase(sDownloadCode)) Then
dicKeepLis.Item(sDownloadCode) = dicKeepLis.Item
(sDownloadCode)&”,”&UCase(Prod)
Else
dicKeepLis.Add UCase(sDownloadCode),UCase(Prod)
End If
End If
Next ‘Prod
End Sub ‘CheckLIS
‘=======================================================================
================================
‘File cleanup operations for the Local Installation Source (MSOCache)
Sub WipeLIS
Const LISROOT = “MSOCache\All Users\”
Dim LogicalDisks, Disk, Folder, SubFolder, MseFolder, File, Files
Dim arrSubFolders
Dim sFolder
Dim fRemoveFolder
Log ” LIS CleanUp”
‘Search all hard disks
Set LogicalDisks = oWmiLocal.ExecQuery(“Select * from
Win32_LogicalDisk”)
For Each Disk in LogicalDisks
If Disk.DriveType = 3 Then
If oFso.FolderExists(Disk.DeviceID & “\” & LISROOT)Then
Set Folder = oFso.GetFolder(Disk.DeviceID & “\” &
LISROOT)
For Each Subfolder in Folder.Subfolders
If InStr(UCase(Subfolder.Name)&”}”,OFFICE_2003)>0
Then
If NOT dicKeepLis.Exists(UCase(Subfolder.Name))
Then DeleteFolder Subfolder.Path
ElseIf LCase(Subfolder.Name) =
“microsoft.watson.alrtintl.data” OR _
LCase(Subfolder.Name) =
“microsoft.watson.watsonrc.data” Then
If NOT dicKeepLis.Count > 0 Then DeleteFolder
Subfolder.Path
End If
Next ‘Subfolder
If (Folder.Subfolders.Count = 0) AND (Folder.Files.Count
= 0) Then
sFolder = Folder.Path
Set Folder = Nothing
SmartDeleteFolder sFolder
End If
End If ‘oFso.FolderExists
End If ‘Disk.DriveType = 3
Next ‘Disk
‘MSECache
If EnumFolders(sProgramFiles,arrSubFolders) Then
For Each SubFolder in arrSubFolders
If UCase(Right(SubFolder,9))=”\MSECACHE” Then
ReDim arrMseFolders(-1)
Set Folder = oFso.GetFolder(SubFolder)
GetMseFolderStructure Folder
For Each MseFolder in arrMseFolders
If oFso.FolderExists(MseFolder) Then
fRemoveFolder = False
Set Folder = oFso.GetFolder(MseFolder)
Set Files = Folder.Files
For Each File in Files
If (LCase(Right(File.Name,4))=”.msi”) Then
If CheckDelete(ProductCode(File.Path))
Then
fRemoveFolder = True
Exit For
End If ‘CheckDelete
End If
Next ‘File
Set Files = Nothing
Set Folder = Nothing
If fRemoveFolder Then SmartDeleteFolder
MseFolder
End If ‘oFso.FolderExists(MseFolder)
Next ‘MseFolder
End If
Next ‘SubFolder
End If ‘oFso.FolderExists
End Sub ‘WipeLis
‘=======================================================================
================================
‘Wipe files and folders
Sub FileWipeAll
‘User specific files
If NOT fKeepUser Then
‘Delete files that should be backed up before deleting them
CopyAndDeleteFile sAppdata & “\Microsoft\Templates\Normal.dot”
End If
‘Run the individual filewipe first
FileWipeIndividual
‘Take care of the rest
DeleteFolder sOInstallRoot
DeleteFolder sCommonProgramFiles & “\Microsoft Shared\Office11″
DeleteFile sAllUsersProfile & “\Application Data\Microsoft\Office
\Data\opa11.dat”
End Sub ‘FileWipeAll
‘=======================================================================
================================
‘Wipe individual files & folders related to SKU’s that are no longer
installed
Sub FileWipeIndividual
Dim LogicalDisks, Disk
Dim File, Files, XmlFile, scFiles, oFile, Folder, SubFolder,
Processes, Process, item
Dim sFile, sFolder, sPath, sConfigName, sContents, sProductCode,
sLocalDrives,sScQuery
Dim arrSubfolders
Dim fDeleteSC
Log ” File CleanUp”
If IsArray(arrDeleteFiles) Then
If fForce Then
Log ” Doing Action: EndOSE”
Set Processes = oWmiLocal.ExecQuery(“Select * From
Win32_Process”)
For Each Process in Processes
If Len(Process.Name)>2 Then
If LCase(Left(Process.Name,3))=”ose” Then
LogOnly ” – Running process : ” & Process.Name
Log ” -> Ending process: ” & Process.Name
Process.Terminate
End If
End If ‘Len>2
Next ‘Process
LogOnly ” End Action: EndOSE”
CloseOfficeApps
End If
‘Wipe individual files detected earlier
LogOnly ” Removing left behind files”
For Each sFile in arrDeleteFiles
If oFso.FileExists(sFile) Then DeleteFile sFile
Next ‘File
End If ‘IsArray
‘Wipe Shortcuts from local hard disks
If NOT fSkipSD Then
On Error Resume Next
Log ” Searching for shortcuts. This can take some time …”
Set LogicalDisks = oWmiLocal.ExecQuery(“Select * From
Win32_LogicalDisk WHERE DriveType=3″)
For Each Disk in LogicalDisks
sLocalDrives = sLocalDrives & UCase(Disk.DeviceID) & “\;”
sScQuery = “Select * From Win32_ShortcutFile WHERE
Drive=’”&Disk.DeviceID&”‘”
Set scFiles = oWmiLocal.ExecQuery(sScQuery)
For Each File in scFiles
fDeleteSC = False
‘Compare if the shortcut target is in the list of
executables that will be removed
If Len(File.Target)>0 Then
For Each item in dicApps.Items
If LCase(File.Target) = item Then
fDeleteSC = True
Exit For
End If
Next ‘item
End If
‘Handle Windows Installer shortcuts
If InStr(File.Target,”{“)>0 Then
If Len(File.Target)>=InStr(File.Target,”{“)+37 Then
If CheckDelete(Mid(File.Target,InStr
(File.Target,”{“),38)) Then fDeleteSC = True
End If
End If
If fDeleteSC Then
If Not IsArray(arrDeleteFolders) Then ReDim
arrDeleteFolders(0)
sFolder = Left(File.Description,InStrRev
(File.Description,”\”)-1)
If Not arrDeleteFolders(UBound(arrDeleteFolders)) =
sFolder Then
ReDim Preserve arrDeleteFolders(UBound
(arrDeleteFolders)+1)
arrDeleteFolders(UBound(arrDeleteFolders)) =
sFolder
End If
DeleteFile File.Description
End If ‘fDeleteSC
Next ‘scFile
Next
On Error Goto 0
End If ‘NOT SkipSD
Err.Clear
End Sub ‘FileWipeIndividual
‘=======================================================================
================================
Sub DelScrubTmp
Dim LogicalDisks, Disk
Dim sFolder
‘Search all hard disks
Set LogicalDisks = oWmiLocal.ExecQuery(“Select * from
Win32_LogicalDisk”)
For Each Disk in LogicalDisks
If Disk.DriveType = 3 Then
If oFso.FolderExists(Disk.DeviceID & “\ScrubTmp”) Then
On Error Resume Next
oFso.DeleteFolder Disk.DeviceID & “\ScrubTmp”,True
On Error Goto 0
End If
End If
Next ‘Disk
End Sub ‘DelScrubTmp
‘=======================================================================
================================
‘Ensure there are no unexpected .msi files in the scrub folder
Sub DeleteMsiScrubCache
Dim Folder, File, Files
Log ” ScrubCache CleanUp”
Set Folder = oFso.GetFolder(sScrubDir) : CheckError
“DeleteMsiScrubCache”
Set Files = Folder.Files
For Each File in Files
CheckError “DeleteMsiScrubCache”
If LCase(Right(File.Name,4))=”.msi” Then
CheckError “DeleteMsiScrubCache”
DeleteFile File.Path : CheckError “DeleteMsiScrubCache”
End If
Next ‘File
End Sub ‘DeleteMsiScrubCache
‘=======================================================================
================================
Sub MsiClearOrphanedFiles
Const USERSIDEVERYONE = “s-1-1-0″
Const MSIINSTALLCONTEXT_ALL = 7
Const MSIPATCHSTATE_ALL = 15
‘Error handling inlined
On Error Resume Next
Dim Patch, AllPatches, Product, AllProducts
Dim File, Files, Folder
Dim sFName, sLocalMsp, sLocalMsi, sPatchList, sMsiList
Set Folder = oFso.GetFolder(sWinDir & “\Installer”)
Set Files = Folder.Files
Log ” Windows Installer cache CleanUp”
‘Get a complete list of patches
Err.Clear
Set AllPatches = oMsi.PatchesEx
(“”,USERSIDEVERYONE,MSIINSTALLCONTEXT_ALL,MSIPATCHSTATE_ALL)
If Err 0 Then
CheckError “MsiClearOrphanedFiles (msp)”
Else
‘Fill a comma separated stringlist with all .msp patchfiles
For Each Patch in AllPatches
sLocalMsp = “” : sLocalMsp = LCase(Patch.Patchproperty
(“LocalPackage”)) : CheckError “MsiClearOrphanedFiles (msp)”
sPatchList = sPatchList & sLocalMsp & “,”
Next ‘Patch
‘Delete all non referenced .msp files from %windir%\installer
For Each File in Files
sFName = “” : sFName = LCase(File.Path)
If LCase(Right(sFName,4)) = “.msp” Then
If Not InStr(sPatchList,sFName) > 0 Then
‘While this is an orphaned file keep the scope of
Office only
If InStr(UCase(MspTargets(File.Path)),OFFICE_2003)>0
Then DeleteFile File.Path
End If
End If ‘LCase(Right(sFName,4))
Next ‘File
End If ‘Err=0
‘Get a complete list products
Err.Clear
Set AllProducts = oMsi.ProductsEx
(“”,USERSIDEVERYONE,MSIINSTALLCONTEXT_ALL)
If Err 0 Then
CheckError “MsiClearOrphanedFiles (msi)”
Else
‘Fill a comma separated stringlist with all .msi files
For Each Product in AllProducts
sLocalMsi = “” : sLocalMsi = LCase(Product.InstallProperty
(“LocalPackage”)) : CheckError “MsiClearOrphanedFiles (msi)”
sMsiList = sMsiList & sLocalMsi & “,”
Next ‘Product
‘Delete all non referenced .msi files from %windir%\installer
For Each File in Files
sFName = “” : sFName = LCase(File.Path)
If LCase(Right(sFName,4)) = “.msi” Then
If Not InStr(sMsiList,sFName) > 0 Then
‘While this is an orphaned file keep the scope of
Office only
If UCase(Right(ProductCode(File.Path),PRODLEN))
=OFFICE_2003 Then DeleteFile File.Path
End If
End If ‘LCase(Right(sFName,4)) = “.msi”
Next ‘File
End If ‘Err=0
End Sub ‘MsiClearOrphanedFiles
‘=======================================================================
================================
Sub RegWipe
Dim Item, Name, Sku
Dim hDefKey, sSubKeyName, sCurKey, sValue, sGuid
Dim arrKeys, arrNames, arrTypes
Dim i, iLoopCnt
Log ” Registry CleanUp”
‘Wipe registry data
‘User Profile settings
RegDeleteKey HKCU,”Software\Policies\Microsoft\Office\11.0″
If fRemoveAll Then
RegDeleteKey HKCU,”SOFTWARE\Microsoft\OfficeCustomizeWizard
\11.0″
End If
If NOT fKeepUser Then
RegDeleteKey HKCU,”Software\Microsoft\Office\11.0″
End If ‘fKeepUser
‘Computer specific settings
If fRemoveAll Then
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Office\11.0″
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Windows NT\CurrentVersion
\Terminal Server\Install\Software\Microsoft\Office\11.0″
RegDeleteKey HKLM,”SOFTWARE\Microsoft\OfficeCustomizeWizard
\11.0″
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Windows NT\CurrentVersion
\Terminal Server\Install\SOFTWARE\Microsoft\OfficeCustomizeWizard\11.0″
‘Jet_Replication
sValue = “”
If RegReadValue(HKCR,”CLSID\{CC2C83A6-9BE4-11D0-98E7-
00C04FC2CAF5}\InprocServer32″,”SystemDB”,sValue,”REG_SZ”) Then
If Len(sValue) > Len(sOInstallRoot) Then
If LCase(Left(sValue,Len(sOInstallRoot))) = LCase
(sOInstallRoot) Then RegDeleteKey HKCR,”CLSID\{CC2C83A6-9BE4-11D0-98E7-
00C04FC2CAF5}\InprocServer32″
End If
End If
‘Win32Assemblies
hDefKey = HKCR
sSubKeyName = “Installer\Win32Assemblies\”
If RegEnumKey(hDefKey,sSubKeyName,arrKeys) Then
For Each Item in arrKeys
If InStr(UCase(Item),”OFFICE11″)>0 Then RegDeleteKey
hDefKey,sSubKeyName & Item
Next ‘Item
End If ‘RegEnumKey
End If ‘fRemoveAll
For iLoopCnt = 1 to 3
Select Case iLoopCnt
Case 1
‘CIW – HKCU
sSubKeyName = “Software\Microsoft\OfficeCustomizeWizard
\11.0\RegKeyPaths\”
hDefKey = HKCU
Case 2
‘CIW – HKLM
sSubKeyName = “SOFTWARE\Microsoft\OfficeCustomizeWizard
\11.0\RegKeyPaths\”
hDefKey = HKLM
Case 3
‘Add/Remove Programs
sSubKeyName = REG_ARP
hDefKey = HKLM
End Select
If RegEnumKey(hDefKey,sSubKeyName,arrKeys) Then
For Each Item in arrKeys
‘OFFICE_2003 id
If Len(Item)>37 Then
sGuid = UCase(Left(Item,38))
If Right(sGuid,PRODLEN)=OFFICE_2003 Then
If CheckDelete(sGuid) Then
RegDeleteKey hDefKey, sSubKeyName & Item
End If
End If ‘Right(Item,PRODLEN)=OFFICE_2003
End If ‘Len(Item)>37
Next ‘Item
If iLoopCnt < 3 Then
If RegEnumValues(hDefKey,sSubKeyName,arrNames,arrTypes)
Then
i = 0
For Each Name in arrNames
If RegReadValue
(hDefKey,sSubKeyName,Name,sValue,arrTypes(i)) Then
If sValue = sGuid Then RegDeleteValue
hDefKey,sSubKeyName,Name
End If
i = i + 1
Next
End If
End If
End If
If NOT RegEnumKey(hDefKey,sSubKeyName,arrKeys) Then RegDeleteKey
hDefKey,”Software\Microsoft\OfficeCustomizeWizard\11.0\”
If NOT RegEnumKey(hDefKey,”Software\Microsoft
\OfficeCustomizeWizard\11.0\”,arrKeys) Then RegDeleteKey
hDefKey,”Software\Microsoft\OfficeCustomizeWizard\”
Next ‘iLoopCnt
‘UpgradeCodes, WI config, WI global config
For iLoopCnt = 1 to 5
Select Case iLoopCnt
Case 1
sSubKeyName = “SOFTWARE\Microsoft\Windows\CurrentVersion
\Installer\UpgradeCodes\”
hDefKey = HKLM
Case 2
sSubKeyName = “Installer\UpgradeCodes\”
hDefKey = HKCR
Case 3
sSubKeyName = “SOFTWARE\Microsoft\Windows\CurrentVersion
\Installer\UserData\S-1-5-18\Products\”
hDefKey = HKLM
Case 4
sSubKeyName = “Installer\Features\”
hDefKey = HKCR
Case 5
sSubKeyName = “Installer\Products\”
hDefKey = HKCR
Case Else
sSubKeyName = “”
hDefKey = “”
End Select
If RegEnumKey(hDefKey,sSubKeyName,arrKeys) Then
For Each Item in arrKeys
‘Ensure we have the expected length for a compressed
GUID
If Len(Item)=32 Then
‘Expand the GUID
sGuid = GetExpandedGuid(Item)
‘Check if it’s a Office 2003 key
If Right(sGuid,PRODLEN)=OFFICE_2003 Then
If fRemoveAll Then
RegDeleteKey hDefKey,sSubKeyName & Item
Else
If iLoopCnt delete the
value
RegDeleteValue hDefKey,
sSubKeyName & Item, Name
End If
Next ‘Name
End If ‘IsArray(arrNames)
‘If all entries were removed – delete
the key
RegEnumValues hDefKey,sSubKeyName &
Item,arrNames,arrTypes
If Not IsArray(arrNames) Then
RegDeleteKey hDefKey, sSubKeyName & Item
Else ‘iLoopCnt >= 3
If CheckDelete(sGuid) Then RegDeleteKey
hDefKey, sSubKeyName & Item
End If ‘iLoopCnt 0 Then
If NOT dicKeepLis.Exists(UCase(Item)) Then RegDeleteKey
HKLM,sSubKeyName & Item
ElseIf LCase(Item) = “microsoft.watson.alrtintl.data” OR _
LCase(Item) = “microsoft.watson.watsonrc.data” Then
If NOT dicKeepLis.Count > 0 Then RegDeleteKey
HKLM,sSubKeyName & Item
End If
Next ‘Item
End If ‘RegEnumKey
‘Registration
hDefKey = HKLM
sSubKeyName = “SOFTWARE\Microsoft\Office\11.0\Registration\”
If RegEnumKey(HKLM,sSubKeyName,arrKeys) Then
For Each Item in arrKeys
If Len(Item)>37 Then
If CheckDelete(UCase(Left(Item,38))) Then RegDeleteKey
HKLM,sSubKeyName & Item
End If
Next ‘Item
End If ‘RegEnumKey
End Sub ‘RegWipeAll
‘=======================================================================
================================
‘=======================================================================
================================
‘ Helper Functions
‘=======================================================================
================================
‘End all running instances of applications that will be removed
Sub CloseOfficeApps
Dim Processes, Process
Log ” Doing Action: CloseOfficeApps”
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Process”)
For Each Process in Processes
If dicApps.Exists(LCase(Process.Name)) Then
Log ” – End process ” & Process.Name
Process.Terminate()
CheckError “CloseOfficeApps: ” & “Process.Name”
End If
Next ‘Process
LogOnly ” End Action: CloseOfficeApps”
End Sub ‘CloseOfficeApps
‘=======================================================================
================================
‘Ensure Windows Explorer is restarted if needed
Sub RestoreExplorer
Dim Processes
‘Non critical routine. Don’t fail on error
On Error Resume Next
wscript.sleep 1000
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Process
Where Name=’explorer.exe’”)
If Processes.Count 1 Then
If Right(sKey,1) = “\” Then sKey = Left(sKey,Len(sKey)-1)
End If
If RegEnumKey(hDefKey,sKey,arrKeys) Then
For Each SubKey in arrKeys
If NOT Len(SubKey) = iValidLength Then
RegDeleteKey hDefKey,sKey & “\” & SubKey
End If
Next ‘SubKey
End If
End Sub ‘EnsureValidWIMetadata
‘=======================================================================
================================
‘Create a backup copy of the file in the ScrubDir then delete the file
Sub CopyAndDeleteFile(sFile)
Dim File
‘Error handling inlined
On Error Resume Next
If oFso.FileExists(sFile) Then
Set File = oFso.GetFile(sFile)
If Not oFso.FolderExists(sScrubDir & “\” &
File.ParentFolder.Name) Then oFso.CreateFolder sScrubDir & “\” &
File.ParentFolder.Name
If Not fDetectOnly Then
LogOnly ” – Backing up file: ” & sFile
oFso.CopyFile sFile,sScrubDir & “\” & File.ParentFolder.Name
& “\” & File.Name,True : CheckError “CopyAndDeleteFile”
Set File = Nothing
DeleteFile(sFile)
Else
LogOnly ” – Simulate CopyAndDelete file: ” & sFile
End If
End If ‘oFso.FileExists
End Sub ‘CopyAndDeleteFile
‘=======================================================================
================================
‘Wrapper to delete a file
Sub DeleteFile(sFile)
Dim File
Dim sFileName, sNewPath
‘Error handling inlined
On Error Resume Next
If oFso.FileExists(sFile) Then
If Not fDetectOnly Then
LogOnly ” – Delete file: ” & sFile
oFso.DeleteFile sFile,True
Else
LogOnly ” – Simulate delete file: ” & sFile
End If
If Err 0 Then
CheckError “DeleteFile”
‘Try to move the file and delete from there
Set File = oFso.GetFile(sFile)
sFileName = File.Name
sNewPath = File.Drive.Path & “\” & “ScrubTmp”
Set File = Nothing
‘Ensure we stay within the same drive
If Not oFso.FolderExists(sNewPath) Then oFso.CreateFolder
(sNewPath)
‘Move the file
LogOnly ” – Move file to: ” & sNewPath & “\” & sFileName
oFso.MoveFile sFile,sNewPath & “\” & sFileName
If Err 0 Then
CheckError “DeleteFile (move)”
Else
If Not InStr(sMoveMessage,sNewPath)>0 Then sMoveMessage
= sMoveMessage & sNewPath & “;”
oFso.DeleteFile sNewPath & “\” & sFileName,True
If Err 0 Then CheckError “DeleteFile (moved)”
End If ‘Err 0
End If ‘Err 0
End If ‘oFso.FileExists
End Sub ‘DeleteFile
‘=======================================================================
================================
’64 bit aware wrapper to return the requested folder
Function GetFolderPath(sPath)
GetFolderPath = True
If oFso.FolderExists(sPath) Then Exit Function
If f64 AND oFso.FolderExists(Wow64Folder(sPath)) Then
sPath = Wow64Folder(sPath)
Exit Function
End If
GetFolderPath = False
End Function ‘GetFolderPath
‘=======================================================================
================================
‘Enumerates subfolder names of a folder and returns True if subfolders
exist
Function EnumFolderNames (sFolder, arrSubFolders)
Dim Folder, Subfolder
Dim sSubFolders
If oFso.FolderExists(sFolder) Then
Set Folder = oFso.GetFolder(sFolder)
For Each Subfolder in Folder.Subfolders
sSubFolders = sSubFolders & Subfolder.Name & “,”
Next ‘Subfolder
End If
If f64 AND oFso.FolderExists(Wow64Folder(sFolder)) Then
Set Folder = oFso.GetFolder(Wow64Folder(sFolder))
For Each Subfolder in Folder.Subfolders
sSubFolders = sSubFolders & Subfolder.Name & “,”
Next ‘Subfolder
End If
If Len(sSubFolders)>0 Then arrSubFolders = RemoveDuplicates(Split
(Left(sSubFolders,Len(sSubFolders)-1),”,”))
EnumFolderNames = Len(sSubFolders)>0
End Function ‘EnumFolderNames
‘=======================================================================
================================
‘Enumerates subfolders of a folder and returns True if subfolders exist
Function EnumFolders (sFolder, arrSubFolders)
Dim Folder, Subfolder
Dim sSubFolders
If oFso.FolderExists(sFolder) Then
Set Folder = oFso.GetFolder(sFolder)
For Each Subfolder in Folder.Subfolders
sSubFolders = sSubFolders & Subfolder.Path & “,”
Next ‘Subfolder
End If
If f64 AND oFso.FolderExists(Wow64Folder(sFolder)) Then
Set Folder = oFso.GetFolder(Wow64Folder(sFolder))
For Each Subfolder in Folder.Subfolders
sSubFolders = sSubFolders & Subfolder.Path & “,”
Next ‘Subfolder
End If
If Len(sSubFolders)>0 Then arrSubFolders = RemoveDuplicates(Split
(Left(sSubFolders,Len(sSubFolders)-1),”,”))
EnumFolders = Len(sSubFolders)>0
End Function ‘EnumFolders
‘=======================================================================
================================
Sub GetMseFolderStructure (Folder)
Dim SubFolder
For Each SubFolder in Folder.SubFolders
ReDim Preserve arrMseFolders(UBound(arrMseFolders)+1)
arrMseFolders(UBound(arrMseFolders)) = SubFolder.Path
GetMseFolderStructure SubFolder
Next ‘SubFolder
End Sub ‘GetMseFolderStructure
‘=======================================================================
================================
‘Wrapper to delete a folder
Sub DeleteFolder(sFolder)
Dim Folder
Dim sDelFolder, sFolderName, sNewPath
If dicKeepFolder.Exists(LCase(sFolder)) Then Exit Sub
If f64 Then
If dicKeepFolder.Exists(LCase(Wow64Folder(sFolder))) Then Exit
Sub
End If
If Len(sFolder) > 1 Then
If Right(sFolder,1) = “\” Then sFolder = Left(sFolder,Len
(sFolder)-1)
End If
‘Error handling inlined
On Error Resume Next
If oFso.FolderExists(sFolder) Then
sDelFolder = sFolder
ElseIf f64 AND oFso.FolderExists(Wow64Folder(sFolder)) Then
sDelFolder = Wow64Folder(sFolder)
Else
Exit Sub
End If
If Not fDetectOnly Then
LogOnly ” – Delete folder: ” & sDelFolder
oFso.DeleteFolder sDelFolder,True
Else
LogOnly ” – Simulate delete folder: ” & sDelFolder
End If
If Err 0 Then
CheckError “DeleteFolder”
‘Try to move the folder and delete from there
Set Folder = oFso.GetFolder(sDelFolder)
sFolderName = Folder.Name
sNewPath = Folder.Drive.Path & “\” & “ScrubTmp”
Set Folder = Nothing
‘Ensure we stay within the same drive
If Not oFso.FolderExists(sNewPath) Then oFso.CreateFolder
(sNewPath)
‘Move the folder
LogOnly ” – Moving folder to: ” & sNewPath & “\” & sFolderName
oFso.MoveFolder sFolder,sNewPath & “\” & sFolderName
If Err 0 Then
CheckError “DeleteFolder (move)”
Else
oFso.DeleteFolder sNewPath & “\” & sFolderName,True
If Err 0 And fForce Then
CheckError “DeleteFolder (moved)”
End If
End If ‘Err 0
End If ‘Err 0
End Sub ‘DeleteFolder
‘=======================================================================
================================
‘Delete empty folder structures
Sub DeleteEmptyFolders
Dim Folder
Dim sFolder
If Not IsArray(arrDeleteFolders) Then Exit Sub
Log ” Empty Folder Cleanup”
For Each sFolder in arrDeleteFolders
If oFso.FolderExists(sFolder) Then
Set Folder = oFso.GetFolder(sFolder)
If (Folder.Subfolders.Count = 0) AND (Folder.Files.Count =
0) Then
Set Folder = Nothing
SmartDeleteFolder sFolder
End If
End If
Next ‘sFolder
End Sub ‘DeleteEmptyFolders
‘=======================================================================
================================
‘Wrapper to delete a folder and remove the empty parent folder structure
Sub SmartDeleteFolder(sFolder)
If oFso.FolderExists(sFolder) Then
If Not fDetectOnly Then
LogOnly “Request SmartDelete for folder: ” & sFolder
SmartDeleteFolderEx sFolder
Else
LogOnly “Simulate request SmartDelete for folder: ” &
sFolder
End If
End If
If f64 AND oFso.FolderExists(Wow64Folder(sFolder)) Then
If Not fDetectOnly Then
LogOnly “Request SmartDelete for folder: ” & Wow64Folder
(sFolder)
SmartDeleteFolderEx Wow64Folder(sFolder)
Else
LogOnly “Simulate request SmartDelete for folder: ” &
Wow64Folder(sFolder)
End If
End If
End Sub ‘SmartDeleteFolder
‘=======================================================================
================================
‘Executes the folder delete operation
Sub SmartDeleteFolderEx(sFolder)
Dim Folder
On Error Resume Next
DeleteFolder sFolder : CheckError “SmartDeleteFolderEx”
On Error Goto 0
Set Folder = oFso.GetFolder(oFso.GetParentFolderName(sFolder))
If (Folder.Subfolders.Count = 0) AND (Folder.Files.Count = 0) Then
SmartDeleteFolderEx(Folder.Path)
End Sub ‘SmartDeleteFolderEx
‘=======================================================================
================================
‘Adds the folder structure to the ‘KeepFolder’ dictionary
Sub AddKeepFolder(sPath)
Dim Folder
If NOT dicKeepFolder.Exists (sPath) Then
dicKeepFolder.Add sPath,sPath
End If
sPath = LCase(oFso.GetParentFolderName(sPath))
If oFso.FolderExists(sPath) Then AddKeepFolder(sPath)
End Sub
‘=======================================================================
================================
‘Handles additional folder-path operations on 64 bit environments
Function Wow64Folder(sFolder)
If LCase(Left(sFolder,Len(sWinDir & “\System32″))) = LCase(sWinDir &
“\System32″) Then
Wow64Folder = sWinDir & “\syswow64″ & Right(sFolder,Len
(sFolder)-Len(sSys32Dir))
ElseIf LCase(Left(sFolder,Len(sProgramFiles))) = LCase
(sProgramFiles) Then
Wow64Folder = sProgramFilesX86 & Right(sFolder,Len(sFolder)-Len
(sProgramFiles))
Else
Wow64Folder = “?” ‘Return invalid string to ensure the folder
cannot exist
End If
End Function ‘Wow64Folder
‘=======================================================================
================================
Function HiveString(hDefKey)
On Error Resume Next
Select Case hDefKey
Case HKCR : HiveString = “HKEY_CLASSES_ROOT”
Case HKCU : HiveString = “HKEY_CURRENT_USER”
Case HKLM : HiveString = “HKEY_LOCAL_MACHINE”
Case HKU : HiveString = “HKEY_USERS”
Case Else : HiveString = hDefKey
End Select
End Function
‘=======================================================================
================================
Function RegKeyExists(hDefKey,sSubKeyName)
Dim arrKeys
RegKeyExists = False
If oReg.EnumKey(hDefKey,sSubKeyName,arrKeys) = 0 Then RegKeyExists =
True
End Function
‘=======================================================================
================================
Function RegValExists(hDefKey,sSubKeyName,sName)
Dim arrValueTypes, arrValueNames
Dim i
RegValExists = False
If Not RegKeyExists(hDefKey,sSubKeyName) Then Exit Function
If oReg.EnumValues(hDefKey,sSubKeyName,arrValueNames,arrValueTypes)
= 0 AND IsArray(arrValueNames) Then
For i = 0 To UBound(arrValueNames)
If LCase(arrValueNames(i)) = Trim(LCase(sName)) Then
RegValExists = True
Next
End If ‘oReg.EnumValues
End Function
‘=======================================================================
================================
‘Read the value of a given registry entry
Function RegReadValue(hDefKey, sSubKeyName, sName, sValue, sType)
Dim RetVal
Dim Item
Dim arrValues
Select Case UCase(sType)
Case “1″,”REG_SZ”
RetVal = oReg.GetStringValue
(hDefKey,sSubKeyName,sName,sValue)
If Not RetVal = 0 AND f64 Then RetVal = oReg.GetStringValue
(hDefKey,Wow64Key(hDefKey, sSubKeyName),sName,sValue)
Case “2″,”REG_EXPAND_SZ”
RetVal = oReg.GetExpandedStringValue
(hDefKey,sSubKeyName,sName,sValue)
If Not RetVal = 0 AND f64 Then RetVal =
oReg.GetExpandedStringValue(hDefKey,Wow64Key(hDefKey,
sSubKeyName),sName,sValue)
Case “7″,”REG_MULTI_SZ”
RetVal = oReg.GetMultiStringValue
(hDefKey,sSubKeyName,sName,arrValues)
If Not RetVal = 0 AND f64 Then RetVal =
oReg.GetMultiStringValue(hDefKey,Wow64Key(hDefKey,
sSubKeyName),sName,arrValues)
If RetVal = 0 Then sValue = Join(arrValues,chr(34))
Case “4″,”REG_DWORD”
RetVal = oReg.GetDWORDValue
(hDefKey,sSubKeyName,sName,sValue)
If Not RetVal = 0 AND f64 Then
RetVal = oReg.GetDWORDValue(hDefKey,Wow64Key(hDefKey,
sSubKeyName),sName,sValue)
End If
Case “3″,”REG_BINARY”
RetVal = oReg.GetBinaryValue
(hDefKey,sSubKeyName,sName,sValue)
If Not RetVal = 0 AND f64 Then RetVal = oReg.GetBinaryValue
(hDefKey,Wow64Key(hDefKey, sSubKeyName),sName,sValue)
Case “11″,”REG_QWORD”
RetVal = oReg.GetQWORDValue
(hDefKey,sSubKeyName,sName,sValue)
If Not RetVal = 0 AND f64 Then RetVal = oReg.GetQWORDValue
(hDefKey,Wow64Key(hDefKey, sSubKeyName),sName,sValue)
Case Else
RetVal = -1
End Select ‘sValue
RegReadValue = (RetVal = 0)
End Function ‘RegReadValue
‘=======================================================================
================================
‘Enumerate a registry key to return all values
Function RegEnumValues(hDefKey,sSubKeyName,arrNames, arrTypes)
Dim RetVal, RetVal64
Dim arrNames32, arrNames64, arrTypes32, arrTypes64
If f64 Then
RetVal = oReg.EnumValues
(hDefKey,sSubKeyName,arrNames32,arrTypes32)
RetVal64 = oReg.EnumValues(hDefKey,Wow64Key(hDefKey,
sSubKeyName),arrNames64,arrTypes64)
If (RetVal = 0) AND (Not RetVal64 = 0) AND IsArray(arrNames32)
AND IsArray(arrTypes32) Then
arrNames = arrNames32
arrTypes = arrTypes32
End If
If (Not RetVal = 0) AND (RetVal64 = 0) AND IsArray(arrNames64)
AND IsArray(arrTypes64) Then
arrNames = arrNames64
arrTypes = arrTypes64
End If
If (RetVal = 0) AND (RetVal64 = 0) AND IsArray(arrNames32) AND
IsArray(arrNames64) AND IsArray(arrTypes32) AND IsArray(arrTypes64) Then
arrNames = RemoveDuplicates(Split((Join(arrNames32,”\”) &
“\” & Join(arrNames64,”\”)),”\”))
arrTypes = RemoveDuplicates(Split((Join(arrTypes32,”\”) &
“\” & Join(arrTypes64,”\”)),”\”))
End If
Else
RetVal = oReg.EnumValues(hDefKey,sSubKeyName,arrNames,arrTypes)
End If ‘f64
RegEnumValues = ((RetVal = 0) OR (RetVal64 = 0)) AND IsArray
(arrNames) AND IsArray(arrTypes)
End Function ‘RegEnumValues
‘=======================================================================
================================
‘Enumerate a registry key to return all subkeys
Function RegEnumKey(hDefKey,sSubKeyName,arrKeys)
Dim RetVal, RetVal64
Dim arrKeys32, arrKeys64
If f64 Then
RetVal = oReg.EnumKey(hDefKey,sSubKeyName,arrKeys32)
RetVal64 = oReg.EnumKey(hDefKey,Wow64Key(hDefKey,
sSubKeyName),arrKeys64)
If (RetVal = 0) AND (Not RetVal64 = 0) AND IsArray(arrKeys32)
Then arrKeys = arrKeys32
If (Not RetVal = 0) AND (RetVal64 = 0) AND IsArray(arrKeys64)
Then arrKeys = arrKeys64
If (RetVal = 0) AND (RetVal64 = 0) Then
If IsArray(arrKeys32) AND IsArray (arrKeys64) Then
arrKeys = RemoveDuplicates(Split((Join(arrKeys32,”\”) &
“\” & Join(arrKeys64,”\”)),”\”))
ElseIf IsArray(arrKeys64) Then
arrKeys = arrKeys64
Else
arrKeys = arrKeys32
End If
End If
Else
RetVal = oReg.EnumKey(hDefKey,sSubKeyName,arrKeys)
End If ‘f64
RegEnumKey = ((RetVal = 0) OR (RetVal64 = 0)) AND IsArray(arrKeys)
End Function ‘RegEnumKey
‘=======================================================================
================================
‘Wrapper around oReg.DeleteValue to handle 64 bit
Sub RegDeleteValue(hDefKey, sSubKeyName, sName)
Dim sWow64Key
Dim iRetVal
If RegValExists(hDefKey,sSubKeyName,sName) Then
On Error Resume Next
If Not fDetectOnly Then
LogOnly ” – Delete registry value: ” & HiveString(hDefKey) &
“\” & sSubKeyName & ” -> ” & sName
iRetVal = 0
iRetVal = oReg.DeleteValue(hDefKey, sSubKeyName, sName)
CheckError “RegDeleteValue”
If NOT (iRetVal=0) Then LogOnly ” Delete failed. Return
value: “&iRetVal
Else
LogOnly ” – Simulate delete registry value: ” & HiveString
(hDefKey) & “\” & sSubKeyName & ” -> ” & sName
End If
On Error Goto 0
End If ‘RegValExists
If f64 Then
sWow64Key = Wow64Key(hDefKey, sSubKeyName)
If RegValExists(hDefKey,sWow64Key,sName) Then
On Error Resume Next
If Not fDetectOnly Then
LogOnly ” – Delete registry value: ” & HiveString(hDefKey) &
“\” & sWow64Key & ” -> ” & sName
iRetVal = 0
iRetVal = oReg.DeleteValue(hDefKey, sWow64Key, sName)
CheckError “RegDeleteValue”
If NOT (iRetVal=0) Then LogOnly ” Delete failed.
Return value: “&iRetVal
Else
LogOnly ” – Simulate delete registry value: ” &
HiveString(hDefKey) & “\” & sWow64Key & ” -> ” & sName
End If
On Error Goto 0
End If ‘RegKeyExists
End If
End Sub ‘RegDeleteValue
‘=======================================================================
================================
‘Wrappper around RegDeleteKeyEx to handle 64bit scenrios
Sub RegDeleteKey(hDefKey, sSubKeyName)
Dim sWow64Key
If RegKeyExists(hDefKey, sSubKeyName) Then
If Not fDetectOnly Then
LogOnly ” – Delete registry key: ” & HiveString(hDefKey) &
“\” & sSubKeyName
On Error Resume Next
RegDeleteKeyEx hDefKey, sSubKeyName
On Error Goto 0
Else
LogOnly ” – Simulate delete registry key: ” & HiveString
(hDefKey) & “\” & sSubKeyName
End If
End If ‘RegKeyExists
If f64 Then
sWow64Key = Wow64Key(hDefKey, sSubKeyName)
If RegKeyExists(hDefKey,sWow64Key) Then
If Not fDetectOnly Then
LogOnly ” – Delete registry key: ” & HiveString(hDefKey)
& “\” & sWow64Key
On Error Resume Next
RegDeleteKeyEx hDefKey, sWow64Key
On Error Goto 0
Else
LogOnly ” – Simulate delete registry key: ” &
HiveString(hDefKey) & “\” & sWow64Key
End If
End If ‘RegKeyExists
End If
End Sub ‘RegDeleteKey
‘=======================================================================
================================
‘Recursively delete a registry structure
Sub RegDeleteKeyEx(hDefKey, sSubKeyName)
Dim arrSubkeys
Dim sSubkey
Dim iRetVal
On Error Resume Next
oReg.EnumKey hDefKey, sSubKeyName, arrSubkeys
If IsArray(arrSubkeys) Then
For Each sSubkey In arrSubkeys
RegDeleteKeyEx hDefKey, sSubKeyName & “\” & sSubkey
Next
End If
If Not fDetectOnly Then
iRetVal = 0
iRetVal = oReg.DeleteKey(hDefKey,sSubKeyName)
If NOT (iRetVal=0) Then LogOnly ” Delete failed. Return
value: “&iRetVal
End If
End Sub ‘RegDeleteKeyEx
‘=======================================================================
================================
‘Return the alternate regkey location on 64bit environment
Function Wow64Key(hDefKey, sSubKeyName)
Dim iPos
Select Case hDefKey
Case HKCU
If Left(sSubKeyName,17) = “Software\Classes\” Then
Wow64Key = Left(sSubKeyName,17) & “Wow6432Node\” &
Right(sSubKeyName,Len(sSubKeyName)-17)
Else
iPos = InStr(sSubKeyName,”\”)
Wow64Key = Left(sSubKeyName,iPos) & “Wow6432Node\” &
Right(sSubKeyName,Len(sSubKeyName)-iPos)
End If
Case HKLM
If Left(sSubKeyName,17) = “Software\Classes\” Then
Wow64Key = Left(sSubKeyName,17) & “Wow6432Node\” &
Right(sSubKeyName,Len(sSubKeyName)-17)
Else
iPos = InStr(sSubKeyName,”\”)
Wow64Key = Left(sSubKeyName,iPos) & “Wow6432Node\” &
Right(sSubKeyName,Len(sSubKeyName)-iPos)
End If
Case Else
Wow64Key = “Wow6432Node\” & sSubKeyName
End Select ‘hDefKey
End Function ‘Wow64Key
‘=======================================================================
================================
‘Remove duplicate entries from a one dimensional array
Function RemoveDuplicates(Array)
Dim Item
Dim oDic
Set oDic = CreateObject(“Scripting.Dictionary”)
For Each Item in Array
If Not oDic.Exists(Item) Then oDic.Add Item,Item
Next ‘Item
RemoveDuplicates = oDic.Keys
End Function ‘RemoveDuplicates
‘=======================================================================
================================
‘Uses WMI to stop a service
Function StopService(sService)
Dim Services, Service
Dim sQuery
On Error Resume Next
sQuery = “Select * From Win32_Service Where Name=’” & sService & “‘”
Set Services = oWmiLocal.Execquery(sQuery)
‘Stop the service
For Each Service in Services
If Service.State = “Started” Then Service.StopService
Next ‘Service
Err.Clear
End Function ‘StopService
‘=======================================================================
================================
‘Delete a service
Sub DeleteService(sService)
Dim Services, Service, Processes, Process
Dim sQuery, sStates
On Error Resume Next
sStates = “STARTED;RUNNING”
sQuery = “Select * From Win32_Service Where Name=’” & sService & “‘”
Set Services = oWmiLocal.Execquery(sQuery)
‘Stop and delete the service
For Each Service in Services
Log ” Found service ” & sService & ” in state ” & Service.State
If InStr(sStates,UCase(Service.State))>0 Then
Service.StopService
‘Ensure no more instances of the service are running
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Process
Where Name=’” & sService & “.exe’”)
For Each Process in Processes
Process.Terminate
Next ‘Process
If Not fDetectOnly Then
Log ” – Deleting Service -> ” & sService
Service.Delete
Else
Log ” – Simulate deleting Service -> ” & sService
End If
Next ‘Service
Set Services = Nothing
Err.Clear
End Sub ‘DeleteService
‘=======================================================================
================================
‘Translation for setup.exe error codes
Function SetupRetVal(RetVal)
Select Case RetVal
Case 0 : SetupRetVal = “Success”
Case 30001,1 : SetupRetVal = “AbstractMethod”
Case 30002,2 : SetupRetVal = “ApiProhibited”
Case 30003,3 : SetupRetVal = “AlreadyImpersonatingAUser”
Case 30004,4 : SetupRetVal = “AlreadyInitialized”
Case 30005,5 : SetupRetVal = “ArgumentNullException”
Case 30006,6 : SetupRetVal = “AssertionFailed”
Case 30007,7 : SetupRetVal = “CABFileAddFailed”
Case 30008,8 : SetupRetVal = “CommandFailed”
Case 30009,9 : SetupRetVal = “ConcatenationFailed”
Case 30010,10 : SetupRetVal = “CopyFailed”
Case 30011,11 : SetupRetVal = “CreateEventFailed”
Case 30012,12 : SetupRetVal = “CustomizationPatchNotFound”
Case 30013,13 : SetupRetVal = “CustomizationPatchNotApplicable”
Case 30014,14 : SetupRetVal = “DuplicateDefinition”
Case 30015,15 : SetupRetVal = “ErrorCodeOnly – Passthrough for
Win32 error”
Case 30016,16 : SetupRetVal = “ExceptionNotThrown”
Case 30017,17 : SetupRetVal = “FailedToImpersonateUser”
Case 30018,18 : SetupRetVal = “FailedToInitializeFlexDataSource”
Case 30019,19 : SetupRetVal = “FailedToStartClassFactories”
Case 30020,20 : SetupRetVal = “FileNotFound”
Case 30021,21 : SetupRetVal = “FileNotOpen”
Case 30022,22 : SetupRetVal = “FlexDialogAlreadyInitialized”
Case 30023,23 : SetupRetVal = “HResultOnly – Passthrough for
HRESULT errors”
Case 30024,24 : SetupRetVal = “HWNDNotFound”
Case 30025,25 : SetupRetVal = “IncompatibleCacheAction”
Case 30026,26 : SetupRetVal = “IncompleteProductAddOns”
Case 30027,27 : SetupRetVal = “InstalledProductStateCorrupt”
Case 30028,28 : SetupRetVal = “InsufficientBuffer”
Case 30029,29 : SetupRetVal = “InvalidArgument”
Case 30030,30 : SetupRetVal = “InvalidCDKey”
Case 30031,31 : SetupRetVal = “InvalidColumnType”
Case 30032,31 : SetupRetVal = “InvalidConfigAddLanguage”
Case 30033,33 : SetupRetVal = “InvalidData”
Case 30034,34 : SetupRetVal = “InvalidDirectory”
Case 30035,35 : SetupRetVal = “InvalidFormat”
Case 30036,36 : SetupRetVal = “InvalidInitialization”
Case 30037,37 : SetupRetVal = “InvalidMethod”
Case 30038,38 : SetupRetVal = “InvalidOperation”
Case 30039,39 : SetupRetVal = “InvalidParameter”
Case 30040,40 : SetupRetVal = “InvalidProductFromARP”
Case 30041,41 : SetupRetVal = “InvalidProductInConfigXml”
Case 30042,42 : SetupRetVal = “InvalidReference”
Case 30043,43 : SetupRetVal = “InvalidRegistryValueType”
Case 30044,44 : SetupRetVal = “InvalidXMLProperty”
Case 30045,45 : SetupRetVal = “InvalidMetadataFile”
Case 30046,46 : SetupRetVal = “LogNotInitialized”
Case 30047,47 : SetupRetVal = “LogAlreadyInitialized”
Case 30048,48 : SetupRetVal = “MissingXMLNode”
Case 30049,49 : SetupRetVal = “MsiTableNotFound”
Case 30050,50 : SetupRetVal = “MsiAPICallFailure”
Case 30051,51 : SetupRetVal = “NodeNotOfTypeElement”
Case 30052,52 : SetupRetVal = “NoMoreGraceBoots”
Case 30053,53 : SetupRetVal = “NoProductsFound”
Case 30054,54 : SetupRetVal = “NoSupportedCulture”
Case 30055,55 : SetupRetVal = “NotYetImplemented”
Case 30056,56 : SetupRetVal = “NotAvailableCulture”
Case 30057,57 : SetupRetVal = “NotCustomizationPatch”
Case 30058,58 : SetupRetVal = “NullReference”
Case 30059,59 : SetupRetVal = “OCTPatchForbidden”
Case 30060,60 : SetupRetVal = “OCTWrongMSIDll”
Case 30061,61 : SetupRetVal = “OutOfBoundsIndex”
Case 30062,62 : SetupRetVal = “OutOfDiskSpace”
Case 30063,63 : SetupRetVal = “OutOfMemory”
Case 30064,64 : SetupRetVal = “OutOfRange”
Case 30065,65 : SetupRetVal = “PatchApplicationFailure”
Case 30066,66 : SetupRetVal = “PreReqCheckFailure”
Case 30067,67 : SetupRetVal = “ProcessAlreadyStarted”
Case 30068,68 : SetupRetVal = “ProcessNotStarted”
Case 30069,69 : SetupRetVal = “ProcessNotFinished”
Case 30070,70 : SetupRetVal = “ProductAlreadyDefined”
Case 30071,71 : SetupRetVal = “ResourceAlreadyTracked”
Case 30072,72 : SetupRetVal = “ResourceNotFound”
Case 30073,73 : SetupRetVal = “ResourceNotTracked”
Case 30074,74 : SetupRetVal = “SQLAlreadyConnected”
Case 30075,75 : SetupRetVal = “SQLFailedToAllocateHandle”
Case 30076,76 : SetupRetVal = “SQLFailedToConnect”
Case 30077,77 : SetupRetVal = “SQLFailedToExecuteStatement”
Case 30078,78 : SetupRetVal = “SQLFailedToRetrieveData”
Case 30079,79 : SetupRetVal = “SQLFailedToSetAttribute”
Case 30080,80 : SetupRetVal = “StorageNotCreated”
Case 30081,81 : SetupRetVal = “StreamNameTooLong”
Case 30082,82 : SetupRetVal = “SystemError”
Case 30083,83 : SetupRetVal = “ThreadAlreadyStarted”
Case 30084,84 : SetupRetVal = “ThreadNotStarted”
Case 30085,85 : SetupRetVal = “ThreadNotFinished”
Case 30086,86 : SetupRetVal = “TooManyProducts”
Case 30087,87 : SetupRetVal = “UnexpectedXMLNodeType”
Case 30088,88 : SetupRetVal = “UnexpectedError”
Case 30089,89 : SetupRetVal = “Unitialized”
Case 30090,90 : SetupRetVal = “UserCancel”
Case 30091,91 : SetupRetVal = “ExternalCommandFailed”
Case 30092,92 : SetupRetVal = “SPDatabaseOverSize”
Case 30093,93 : SetupRetVal = “IntegerTruncation”
‘msiexec return values
Case 1259 : SetupRetVal = “APPHELP_BLOCK”
Case 1601 : SetupRetVal = “INSTALL_SERVICE_FAILURE”
Case 1602 : SetupRetVal = “INSTALL_USEREXIT”
Case 1603 : SetupRetVal = “INSTALL_FAILURE”
Case 1604 : SetupRetVal = “INSTALL_SUSPEND”
Case 1605 : SetupRetVal = “UNKNOWN_PRODUCT”
Case 1606 : SetupRetVal = “UNKNOWN_FEATURE”
Case 1607 : SetupRetVal = “UNKNOWN_COMPONENT”
Case 1608 : SetupRetVal = “UNKNOWN_PROPERTY”
Case 1609 : SetupRetVal = “INVALID_HANDLE_STATE”
Case 1610 : SetupRetVal = “BAD_CONFIGURATION”
Case 1611 : SetupRetVal = “INDEX_ABSENT”
Case 1612 : SetupRetVal = “INSTALL_SOURCE_ABSENT”
Case 1613 : SetupRetVal = “INSTALL_PACKAGE_VERSION”
Case 1614 : SetupRetVal = “PRODUCT_UNINSTALLED”
Case 1615 : SetupRetVal = “BAD_QUERY_SYNTAX”
Case 1616 : SetupRetVal = “INVALID_FIELD”
Case 1618 : SetupRetVal = “INSTALL_ALREADY_RUNNING”
Case 1619 : SetupRetVal = “INSTALL_PACKAGE_OPEN_FAILED”
Case 1620 : SetupRetVal = “INSTALL_PACKAGE_INVALID”
Case 1621 : SetupRetVal = “INSTALL_UI_FAILURE”
Case 1622 : SetupRetVal = “INSTALL_LOG_FAILURE”
Case 1623 : SetupRetVal = “INSTALL_LANGUAGE_UNSUPPORTED”
Case 1624 : SetupRetVal = “INSTALL_TRANSFORM_FAILURE”
Case 1625 : SetupRetVal = “INSTALL_PACKAGE_REJECTED”
Case 1626 : SetupRetVal = “FUNCTION_NOT_CALLED”
Case 1627 : SetupRetVal = “FUNCTION_FAILED”
Case 1628 : SetupRetVal = “INVALID_TABLE”
Case 1629 : SetupRetVal = “DATATYPE_MISMATCH”
Case 1630 : SetupRetVal = “UNSUPPORTED_TYPE”
Case 1631 : SetupRetVal = “CREATE_FAILED”
Case 1632 : SetupRetVal = “INSTALL_TEMP_UNWRITABLE”
Case 1633 : SetupRetVal = “INSTALL_PLATFORM_UNSUPPORTED”
Case 1634 : SetupRetVal = “INSTALL_NOTUSED”
Case 1635 : SetupRetVal = “PATCH_PACKAGE_OPEN_FAILED”
Case 1636 : SetupRetVal = “PATCH_PACKAGE_INVALID”
Case 1637 : SetupRetVal = “PATCH_PACKAGE_UNSUPPORTED”
Case 1638 : SetupRetVal = “PRODUCT_VERSION”
Case 1639 : SetupRetVal = “INVALID_COMMAND_LINE”
Case 1640 : SetupRetVal = “INSTALL_REMOTE_DISALLOWED”
Case 1641 : SetupRetVal = “SUCCESS_REBOOT_INITIATED”
Case 1642 : SetupRetVal = “PATCH_TARGET_NOT_FOUND”
Case 1643 : SetupRetVal = “PATCH_PACKAGE_REJECTED”
Case 1644 : SetupRetVal = “INSTALL_TRANSFORM_REJECTED”
Case 1645 : SetupRetVal = “INSTALL_REMOTE_PROHIBITED”
Case 1646 : SetupRetVal = “PATCH_REMOVAL_UNSUPPORTED”
Case 1647 : SetupRetVal = “UNKNOWN_PATCH”
Case 1648 : SetupRetVal = “PATCH_NO_SEQUENCE”
Case 1649 : SetupRetVal = “PATCH_REMOVAL_DISALLOWED”
Case 1650 : SetupRetVal = “INVALID_PATCH_XML”
Case 3010 : SetupRetVal = “SUCCESS_REBOOT_REQUIRED”
Case Else : SetupRetVal = “Unknown Return Value”
End Select
End Function ‘SetupRetVal
‘=======================================================================
================================
Function GetProductID(sProdID)
Dim sReturn
Select Case sProdId
Case “11″ : sReturn = “PRO”
Case “12″ : sReturn = “STANDARD”
Case “13″ : sReturn = “BASIC”
Case “14″ : sReturn = “WSS2″
Case “15″ : sReturn = “Access”
Case “16″ : sReturn = “Excel”
Case “17″ : sReturn = “FrontPage”
Case “18″ : sReturn = “PowerPoint”
Case “19″ : sReturn = “Publisher”
Case “1A” : sReturn = “Outlook”
Case “1B” : sReturn = “Word”
Case “1C” : sReturn = “AccessRuntime”
Case “1E” : sReturn = “OfficeMUI”
Case “1F” : sReturn = “PTK”
Case “23″ : sReturn = “OfficeMUI”
Case “24″ : sReturn = “ORK”
Case “26″ : sReturn = “XPWebComponents”
Case “2E” : sReturn = “OSSSDK”
Case “32″ : sReturn = “PrjSrv”
Case “33″ : sReturn = “PERSONAL”
Case “3A” : sReturn = “PrjStd”
Case “3B” : sReturn = “PrjPro”
Case “3C” : sReturn = “PrjMUI”
Case “44″ : sReturn = “InfoPath”
Case “48″ : sReturn = “InfoPathVSToolkit”
Case “49″ : sReturn = “PIA”
Case “51″ : sReturn = “VisPro”
Case “52″ : sReturn = “VisView”
Case “53″ : sReturn = “VisStd”
Case “55″ : sReturn = “VisEA”
Case “5E” : sReturn = “VisMUI”
Case “83″ : sReturn = “HtmlView”
Case “84″ : sReturn = “XLView”
Case “85″ : sReturn = “WDView”
Case “92″ : sReturn = “WSS2Pack”
Case “93″ : sReturn = “OWP&C”
Case “A1″ : sReturn = “OneNote”
Case “A4″ : sReturn = “OWC”
Case “A5″ : sReturn = “WSSMig”
Case “A9″ : sReturn = “InterConnect”
Case “AA” : sReturn = “PPTCast”
Case “AB” : sReturn = “PPTPack1″
Case “AC” : sReturn = “PPTPack2″
Case “AD” : sReturn = “PPTPack3″
Case “AE” : sReturn = “OrgChart”
Case “CA” : sReturn = “SmallBusiness”
Case “D0″ : sReturn = “AccessDE”
Case “DC” : sReturn = “SmartDocSDK”
Case “E0″ : sReturn = “Outlook”
Case “E3″ : sReturn = “PROPLUS”
Case “F7″ : sReturn = “InfoPathVST”
Case “F8″ : sReturn = “RHDTool”
Case “FD” : sReturn = “Outlook”
Case “FF” : sReturn = “LIP”
Case Else : sReturn = ProdId
End Select ‘ProdId
GetProductID = sReturn
End Function ‘GetProductID
‘=======================================================================
================================
Sub Log (sLog)
wscript.echo sLog
LogStream.WriteLine sLog
End Sub ‘Log
‘=======================================================================
================================
Sub LogOnly (sLog)
LogStream.WriteLine sLog
End Sub ‘Log
‘=======================================================================
================================
Sub CheckError(sModule)
If Err 0 Then
LogOnly Now & ” – ” & sModule & ” – Source: ” & Err.Source & “;
Err# (Hex): ” & Hex( Err ) & _
“; Err# (Dec): ” & Err & “; Description : ” &
Err.Description
End If ‘Err = 0
Err.Clear
End Sub
‘=======================================================================
================================
‘Command line parser
Sub ParseCmdLine
Dim iCnt, iArgCnt
Dim arrArguments
Dim sArg0
iArgCnt = Wscript.Arguments.Count
If iArgCnt = 0 Then
‘Create the log
CreateLog
Log “No argument specified. Preparing user prompt” & vbCrLf
FindInstalledO11Products
If dicInstalledSku.Count > 0 Then sDefault = Join
(RemoveDuplicates(dicInstalledSku.Items),”,”) Else sDefault = “ALL”
sDefault = InputBox(“Enter a list of Office 2003 products to
remove” & vbCrLf & vbCrLf & _
“Examples:” & vbCrLf & _
“ALL” & vbTab & vbTab & “-> remove all of Office 2003″ &
vbCrLf & _
“ProPlus,PrjPro” & vbTab & “-> remove ProPlus and
Project” & vbCrLf &_
“?” & vbTab & vbTab & “-> display Help”, _
“OffScrub03 – Office 2003 remover”, _
sDefault)
If IsEmpty(sDefault) Then ‘User cancelled
Log “User cancelled. CleanUp & Exit.”
wscript.quit
End If ‘IsEmpty(sDefault)
Log “Answer from prompt: ” & sDefault & vbCrLf
sDefault = Trim(UCase(Trim(Replace(sDefault,Chr(34),””))))
arrArguments = Split(Trim(sDefault),” “)
If UBound(arrArguments) = -1 Then ReDim arrArguments(0)
Else
ReDim arrArguments(iArgCnt-1)
For iCnt = 0 To (iArgCnt-1)
arrArguments(iCnt) = UCase(Wscript.Arguments(iCnt))
Next ‘iCnt
End If
‘Handle the SKU list
sArg0 = Replace(arrArguments(0),”/”,””)
sArg0 = Replace(sArg0,”-”,””)
Select Case sArg0
Case “?”
ShowSyntax
Case “ALL”
fRemoveAll = True
fRemoveOSE = False
Case “ALL,OSE”,”OSE,ALL”
fRemoveAll = True
fRemoveOSE = True
Case Else
fRemoveAll = False
fRemoveOSE = False
sSkuRemoveList = arrArguments(0)
End Select
For iCnt = 0 To UBound(arrArguments)
Select Case arrArguments(iCnt)
Case “?”,”/?”,”-?”
ShowSyntax
Case “/B”,”/BYPASS”
If UBound(arrArguments)>iCnt Then
If InStr(arrArguments(iCnt+1),”1″)>0 Then fBypass_Stage1
= True
If InStr(arrArguments(iCnt+1),”2″)>0 Then fBypass_Stage2
= True
If InStr(arrArguments(iCnt+1),”3″)>0 Then fBypass_Stage3
= True
End If
Case “/D”,”/DELETEUSERSETTINGS”
fKeepUser = False
Case “/F”,”/FORCE”
fForce = True
fRemoveOSE = True
Case “/L”,”/LOG”
fLogInitialized = False
If UBound(arrArguments)>iCnt Then
If oFso.FolderExists(arrArguments(iCnt+1)) Then
sLogDir = arrArguments(iCnt+1)
Else
On Error Resume Next
oFso.CreateFolder(arrArguments(iCnt+1))
If Err 0 Then sLogDir = sScrubDir Else sLogDir =
arrArguments(iCnt+1)
End If
End If
Case “/O”,”/OSE”
fRemoveOSE = True
Case “/P”,”/PREVIEW”,”/DETECTONLY”
fDetectOnly = True
Case “/Q”,”/QUIET”
fQuiet = True
Case “/S”,”/SKIPSD”,”/SKIPSHORTCUSTDETECTION”
fSkipSD = True
Case Else
End Select
Next ‘iCnt
If Not fLogInitialized Then CreateLog
End Sub ‘ParseCmdLine
‘=======================================================================
================================
Sub CreateLog
Dim DateTime
Dim sLogName
On Error Resume Next
‘Create the log file
Set DateTime = CreateObject(“WbemScripting.SWbemDateTime”)
DateTime.SetVarDate Now,True
sLogName = sLogDir & “\” & oWShell.ExpandEnvironmentStrings
(“%COMPUTERNAME%”)
sLogName = sLogName & “_” & Left(DateTime.Value,14)
sLogName = sLogName & “_ScrubLog.txt”
Err.Clear
Set LogStream = oFso.CreateTextFile(sLogName,True,True)
If Err 0 Then
Err.Clear
sLogDir = sScrubDir
sLogName = sLogDir & “\” & oWShell.ExpandEnvironmentStrings
(“%COMPUTERNAME%”)
sLogName = sLogName & “_” & Left(DateTime.Value,14)
sLogName = sLogName & “_ScrubLog.txt”
Set LogStream = oFso.CreateTextFile(sLogName,True,True)
End If
Log “Microsoft Customer Support Services – Office 2003 Removal
Utility” & vbCrLf & vbCrLf & _
“Version: ” & VERSION & vbCrLf & _
“64 bit OS: ” & f64 & vbCrLf & _
“Start removal: ” & Now & vbCrLf
fLogInitialized = True
End Sub ‘CreateLog
‘=======================================================================
================================
Sub RelaunchAsCScript
Dim Argument
Dim sCmdLine
sCmdLine = “cmd.exe /k ” & WScript.Path & “\cscript.exe //NOLOGO ” &
Chr(34) & WScript.scriptFullName & Chr(34)
If Wscript.Arguments.Count > 0 Then
For Each Argument in Wscript.Arguments
sCmdLine = sCmdLine & ” ” & chr(34) & Argument & chr(34)
Next ‘Argument
End If
oWShell.Run sCmdLine,1,False
Wscript.Quit
End Sub ‘RelaunchAsCScript
‘=======================================================================
================================
‘Show the expected syntax for the script usage
Sub ShowSyntax
Wscript.Echo sErr & vbCrLf & _
“OffScrub03 V ” & VERSION & vbCrLf & _
“Copyright (c) Microsoft Corporation. All Rights Reserved”
& vbCrLf & vbCrLf & _
“OffScrub03 helps to remove Office 2003 when a regular
uninstall is no longer possible” & vbCrLf & vbCrLf & _
“Usage:” & vbTab & “OffScrub03.vbs [List of config
ProductIDs] [Options]” & vbCrLf & vbCrLf & _
vbTab & “/? ‘ Displays this
help”& vbCrLf &_
vbTab & “/DeleteUserSettings ‘ Deletes some
user profile contents & data”& vbCrLf &_
vbTab & “/Force ‘ Enforces file
removal. May cause data loss!” & vbCrLf &_
vbTab & “/SkipShortcutDetection ‘ Does not search
the local hard drives for shortcuts” & vbCrLf & _
vbTab & “/Log [LogfolderPath] ‘ Custom folder
for log files” & vbCrLf & _
vbTab & “/OSE ‘ Forces removal
of the Office Source Engine service” & vbCrLf &_
vbTab & “/Quiet ‘ Setup.exe and
Msiexec.exe run quiet with no UI” & vbCrLf &_
vbTab & “/Preview ‘ Run this script
to preview what would get removed”& vbCrLf & vbCrLf & _
“Examples:”& vbCrLf & _
vbTab & “OffScrub03.vbs ALL ‘ Remove all
Office 2003 products” & vbCrLf &_
vbTab & “OffScrub03.vbs ProPlus,PrjPro ‘ Remove ProPlus
and Project” & vbCrLf
Wscript.Quit
End Sub ‘ShowSyntax
‘=======================================================================
================================
****
MS Office 2007 removal script
***
‘=======================================================================================================
‘ Name: OffScrub07.vbs
‘ Author: Microsoft Customer Support Services
‘ Copyright (c) 2008,2009,2010 Microsoft Corporation
‘ Script to remove (scrub) Office 2007 products
‘=======================================================================================================
Option Explicit
Const SCRIPTVERSION = “1.28″
Const SCRIPTFILE = “OffScrub07.vbs”
Const SCRIPTNAME = “OffScrub07″
Const OVERSION = “12.0″
Const OVERSIONMAJOR = “12″
Const OREF = “Office12″
Const OREGREF = “”
Const ONAME = “Office 2007″
Const OPACKAGE = “PackageIds”
Const OFFICEID = “0000000FF1CE}”
Const HKCR = &H80000000
Const HKCU = &H80000001
Const HKLM = &H80000002
Const HKU = &H80000003
Const FOR_WRITING = 2
Const PRODLEN = 13
Const COMPPERMANENT = “00000000000000000000000000000000″
Const UNCOMPRESSED = 38
Const COMPRESSED = 32
Const REG_ARP = “SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\”
Const VB_YES = 6
‘=======================================================================================================
Dim oFso, oMsi, oReg, oWShell, oWmiLocal
Dim ComputerItem, Item, LogStream, TmpKey
Dim arrTmpSKUs, arrDeleteFiles, arrDeleteFolders, arrMseFolders
Dim dicKeepProd, dicKeepLis, dicApps, dicKeepFolder, dicDelRegKey, dicKeepReg
Dim dicInstalledSku, dicRemoveSku, dicKeepSku, dicSrv, dicCSuite, dicCSingle
Dim f64, fLegacyProductFound
Dim sErr, sTmp, sSkuRemoveList, sDefault, sWinDir, sMode
Dim sAppData, sTemp, sScrubDir, sProgramFiles, sProgramFilesX86, sCommonProgramFiles, sCommonProgramFilesX86
Dim sAllusersProfile
Dim sProgramData, sLocalAppData, sOInstallRoot
‘=======================================================================================================
‘Main
‘=======================================================================================================
‘Configure defaults
Dim sLogDir : sLogDir = “”
Dim sMoveMessage: sMoveMessage = “”
Dim fRemoveOse : fRemoveOse = False
Dim fRemoveOspp : fRemoveOspp = False
Dim fRemoveAll : fRemoveAll = False
Dim fRemoveC2R : fRemoveC2R = False
Dim fRemoveAppV : fRemoveAppV = False
Dim fRemoveCSuites : fRemoveCSuites = False
Dim fRemoveCSingle : fRemoveCSingle = False
Dim fRemoveSrv : fRemoveSrv = False
Dim fKeepUser : fKeepUser = True ‘Default to keep per user settings
Dim fSkipSD : fSkipSD = False ‘Default to not Skip the Shortcut Detection
Dim fDetectOnly : fDetectOnly = False
Dim fQuiet : fQuiet = False
Dim fNoCancel : fNoCancel = False
Dim fElevated : fElevated = False
‘CAUTION! -> “fForce” will kill running applications which can result in data loss! “fForce” will kill running applications which can result in data loss! 0
If f64 Then Exit For
Next
If f64 Then sProgramFilesX86 = oWShell.ExpandEnvironmentStrings(“%programfiles(x86)%”)
If f64 Then sCommonProgramFilesX86 = oWShell.ExpandEnvironmentStrings(“%CommonProgramFiles(x86)%”)
‘Ensure CScript as engine
If Not UCase(Mid(Wscript.FullName, Len(Wscript.Path) + 2, 1)) = “C” Then RelaunchAsCScript
‘Create Dictionaries
Set dicKeepProd = CreateObject(“Scripting.Dictionary”)
Set dicInstalledSku = CreateObject(“Scripting.Dictionary”)
Set dicRemoveSku = CreateObject(“Scripting.Dictionary”)
Set dicKeepSku = CreateObject(“Scripting.Dictionary”)
Set dicKeepLis = CreateObject(“Scripting.Dictionary”)
Set dicKeepFolder = CreateObject(“Scripting.Dictionary”)
Set dicApps = CreateObject(“Scripting.Dictionary”)
Set dicDelRegKey = CreateObject(“Scripting.Dictionary”)
Set dicKeepReg = CreateObject(“Scripting.Dictionary”)
Set dicSrv = CreateObject(“Scripting.Dictionary”)
Set dicCSuite = CreateObject(“Scripting.Dictionary”)
Set dicCSingle = CreateObject(“Scripting.Dictionary”)
‘Create the temp folder
If Not oFso.FolderExists(sScrubDir) Then oFso.CreateFolder sScrubDir
‘Set the default logging directory
sLogDir = sScrubDir
‘Call the command line parser
ParseCmdLine
If Not CheckRegPermissions Then
‘Try to relaunch elevated
If NOT fQuiet Then RelaunchElevated
‘Can’t relaunch. Exit out
Log “Insufficient registry access permissions – exiting”
‘Undo temporary entries created in ARP
TmpKeyCleanUp
wscript.quit
End If
‘Get Office Install Folder
If NOT RegReadValue(HKLM,”SOFTWARE\Microsoft\Office\”&OVERSION&”\Common\InstallRoot”,”Path”,sOInstallRoot,”REG_SZ”) Then
sOInstallRoot = sProgramFiles & “\Microsoft Office\”&OREF
End If
‘Ensure integrity of WI metadata which could fail used APIs otherwise
EnsureValidWIMetadata HKCU,”Software\Classes\Installer\Products”,COMPRESSED
EnsureValidWIMetadata HKCR,”Installer\Products”,COMPRESSED
EnsureValidWIMetadata HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products”,COMPRESSED
EnsureValidWIMetadata HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components”,COMPRESSED
EnsureValidWIMetadata HKCR,”Installer\Components”,COMPRESSED
‘Add initial known .exe files that might need to be closed
dicApps.Add “communicator.exe”,”communicator.exe”
Select Case OVERSIONMAJOR
Case “12″
Case “14″
dicApps.Add “bcssync.exe”,”bcssync.exe”
dicApps.Add “officesas.exe”,”officesas.exe”
dicApps.Add “officesasscheduler.exe”,”officesasscheduler.exe”
dicApps.Add “msosync.exe”,”msosync.exe”
dicApps.Add “onenotem.exe”,”onenotem.exe”
Case Else
End Select
‘——————-
‘Stage # 0 – Basics |
‘——————-
‘Build a list with installed/registered Office products
sTmp = “Stage # 0 ” & chr(34) & “Basics” & chr(34) & ” (” & Time & “)”
Log vbCrLf & sTmp & vbCrLf & String(Len(sTmp),”=”) & vbCrLf
FindInstalledOProducts
If dicInstalledSku.Count > 0 Then Log “Found registered product(s): ” & Join(RemoveDuplicates(dicInstalledSku.Items),”,”) &vbCrLf
‘Validate the list of products we got from the command line if applicable
ValidateRemoveSkuList
‘Log detection results
If dicRemoveSku.Count > 0 Then Log “Product(s) to be removed: ” & Join(RemoveDuplicates(dicRemoveSku.Items),”,”)
sMode = “Selected ” & ONAME & ” products”
If Not dicRemoveSku.Count > 0 Then sMode = “Orphaned ” & ONAME & ” products”
If fRemoveAll Then sMode = “All ” & ONAME & ” products”
Log “Final removal mode: ” & sMode
Log “Remove OSE service: ” & fRemoveOse &vbCrLf
‘Log preview mode if applicable
If fDetectOnly Then Log “*************************************************************************”
If fDetectOnly Then Log “* PREVIEW MODE *”
If fDetectOnly Then Log “* All uninstall and delete operations will only be logged not executed! *”
If fDetectOnly Then Log “*************************************************************************” & vbCrLf
‘Check if there are legacy products installed
CheckForLegacyProducts
If fLegacyProductFound Then Log “Found legacy Office products that will not be removed.” Else Log “No legacy Office products found.”
‘Cache .msi files
If dicRemoveSku.Count > 0 Then CacheMsiFiles
‘——————————–
‘Stage # 1 – Component Detection |
‘——————————–
sTmp = “Stage # 1 ” & chr(34) & “Component Detection” & chr(34) & ” (” & Time & “)”
Log vbCrLf & sTmp & vbCrLf & String(Len(sTmp),”=”) & vbCrLf
If Not fBypass_Stage1 Then
‘Build a list with files which are installed/registered to a product that’s going to be removed
Log “Prepare for CleanUp stages.”
Log “Identifying removable elements. This can take several minutes.”
ScanComponents
Else
Log “Skipping Component Detection because bypass was requested.”
End If
‘End all running Office applications
If fForce OR fQuiet Then CloseOfficeApps
‘———————-
‘Stage # 2 – Setup.exe |
‘———————-
sTmp = “Stage # 2 ” & chr(34) & “Setup.exe” & chr(34) & ” (” & Time & “)”
Log vbCrLf & sTmp & vbCrLf & String(Len(sTmp),”=”) & vbCrLf
If Not fBypass_Stage2 Then
SetupExeRemoval
Else
Log “Skipping Setup.exe because bypass was requested.”
End If
‘————————
‘Stage # 3 – Msiexec.exe |
‘————————
sTmp = “Stage # 3 ” & chr(34) & “Msiexec.exe” & chr(34) & ” (” & Time & “)”
Log vbCrLf & sTmp & vbCrLf & String(Len(sTmp),”=”) & vbCrLf
If Not fBypass_Stage3 Then
MsiexecRemoval
Else
Log “Skipping Msiexec.exe because bypass was requested.”
End If
‘——————–
‘Stage # 4 – CleanUp |
‘——————–
‘Removal of files and registry settings
sTmp = “Stage # 4 ” & chr(34) & “CleanUp” & chr(34) & ” (” & Time & “)”
Log vbCrLf & sTmp & vbCrLf & String(Len(sTmp),”=”) & vbCrLf
If Not fBypass_Stage4 Then
‘Office Source Engine
If fRemoveOse Then RemoveOSE
‘Softgrid Service
If fRemoveAppV Then RemoveSG
‘Local Installation Source (MSOCache)
WipeLIS
‘Obsolete files
If fRemoveAll Then
FileWipeAll
Else
FileWipeIndividual
End If
‘Empty Folders
DeleteEmptyFolders
‘Restore Explorer if needed
If fForce Then RestoreExplorer
‘Registry data
RegWipe
‘Wipe orphaned files from Windows Installer cache
MsiClearOrphanedFiles
‘Temporary .msi files in scrubcache
DeleteMsiScrubCache
‘Temporary files
DelScrubTmp
Else
Log “Skipping CleanUp because bypass was requested.”
End If
If Not sMoveMessage = “” Then Log vbCrLf & “Please remove this folder after next reboot: ” & sMoveMessage
‘THE END
Log vbCrLf & “End removal: ” & Now & vbCrLf
Log vbCrLf & “For detailed logging please refer to the log in folder ” &chr(34)&sScrubDir&chr(34)&vbCrLf
If fRebootRequired Then
Log vbCrLf & “A restart is required to complete the operation!”
If NOT fQuiet Then
If MsgBox(“Do you want to reboot now?”,vbYesNo,”Reboot Required”) = VB_YES Then
Dim colOS, oOS
Dim oWmiReboot
Set oWmiReboot = GetObject(“winmgmts:{impersonationLevel=impersonate,(Shutdown)}!\\.\root\cimv2″)
Set colOS = oWmiReboot.ExecQuery (“Select * from Win32_OperatingSystem”)
For Each oOS in colOS
oOS.Reboot()
Next
End If
End If
End If
‘=======================================================================================================
‘=======================================================================================================
‘Stage 0 – 4 Subroutines
‘=======================================================================================================
‘Office configuration products are listed with their configuration product name in the “Uninstall” key
‘To identify an Office configuration product all of these condiditions have to be met:
‘ – “SystemComponent” does not have a value of “1″ (DWORD)
‘ – “OPACKAGE” (see constant declaration) entry exists and is not empty
‘ – “DisplayVersion” exists and the 2 leftmost digits are “OVERSIONMAJOR”
Sub FindInstalledOProducts
Dim ArpItem
Dim hDefKey, sCurKey, sName, sValue, sConfigName, sLcid, sProdC, sCVHValue
Dim sProductCodeList, sProductCode
Dim arrKeys, arrValues, arrMultiSzValues, arrProdC
Dim fSystemComponent0, fPackages, fDisplayVersion, fReturn, fCategorized
If dicInstalledSku.Count > 0 Then Exit Sub ‘Already done from InputBox prompt
‘Locate standalone Office products that have no configuration product entry and create a
‘temporary configuration entry
ReDim arrTmpSKUs(-1)
If RegEnumKey(HKLM,REG_ARP,arrKeys) Then
For Each ArpItem in arrKeys
If Len(ArpItem) = 38 Then
If UCase(Right(ArpItem,PRODLEN))=OFFICEID AND Mid(ArpItem,4,2)=OVERSIONMAJOR Then
sCurKey = REG_ARP & ArpItem & “\”
fSystemComponent0 = Not (RegReadValue(HKLM,sCurKey,”SystemComponent”,sValue,”REG_DWORD”) AND (sValue = “1″))
If (fSystemComponent0 AND (NOT RegReadValue(HKLM,sCurKey,”CVH”,sCVHValue,”REG_DWORD”))) Then
RegReadValue HKLM,sCurKey,”DisplayVersion”,sValue,”REG_SZ”
Redim arrMultiSzValues(0)
‘Logic changed to drop the LCID identifier
‘sConfigName = GetProductID(Mid(ArpItem,11,4)) & “_” & CInt(“&h” & Mid(ArpItem,16,4))
sConfigName = OREGREF & GetProductID(Mid(ArpItem,11,4))
If NOT RegKeyExists(HKLM,REG_ARP&sConfigName) Then
‘Create a new ARP item
ReDim Preserve arrTmpSKUs(UBound(arrTmpSKUs)+1)
arrTmpSKUs(UBound(arrTmpSKUs)) = sConfigName
oReg.CreateKey HKLM,REG_ARP & sConfigName
arrMultiSzValues(0) = sConfigName
oReg.SetMultiStringValue HKLM,REG_ARP & sConfigName,OPACKAGE,arrMultiSzValues
arrMultiSzValues(0) = ArpItem
oReg.SetMultiStringValue HKLM,REG_ARP & sConfigName,”ProductCodes”,arrMultiSzValues
oReg.SetStringValue HKLM,REG_ARP & sConfigName,”DisplayVersion”,sValue
oReg.SetDWordValue HKLM,REG_ARP & sConfigName,”SystemComponent”,0
Else
‘Update the existing temporary ARP item
fReturn = RegReadValue(HKLM,REG_ARP&sConfigName,”ProductCodes”,sProdC,”REG_MULTI_SZ”)
If NOT InStr(sProdC,ArpItem)>0 Then sProdC = sProdC & chr(34) & ArpItem
oReg.SetMultiStringValue HKLM,REG_ARP & sConfigName,”ProductCodes”,Split(sProdC,chr(34))
End If ‘RegKeyExists
End If ‘fSystemComponent0
End If ‘OFFICEID
End If ‘Len 38
Next ‘ArpItem
End If ‘RegEnumKey
‘Find the configuration products
If RegEnumKey(HKLM,REG_ARP,arrKeys) Then
For Each ArpItem in arrKeys
sCurKey = REG_ARP & ArpItem & “\”
sValue = “”
fSystemComponent0 = NOT (RegReadValue(HKLM,sCurKey,”SystemComponent”,sValue,”REG_DWORD”) AND (sValue = “1″))
fPackages = RegReadValue(HKLM,sCurKey,OPACKAGE,sValue,”REG_MULTI_SZ”)
fDisplayVersion = RegReadValue(HKLM,sCurKey,”DisplayVersion”,sValue,”REG_SZ”)
If fDisplayVersion Then
If Len(sValue) > 1 Then
fDisplayVersion = (Left(sValue,2) = OVERSIONMAJOR)
Else
fDisplayVersion = False
End If
End If
If (fSystemComponent0 AND fPackages AND fDisplayVersion) OR (fSystemComponent0 AND fDisplayVersion AND InStr(UCase(ArpItem),”CLICK2RUN”)>0) Then
If InStr(ArpItem,”.”)>0 Then sConfigName = UCase(Mid(ArpItem,InStr(ArpItem,”.”)+1)) Else sConfigName = UCase(ArpItem)
If NOT dicInstalledSku.Exists(sConfigName) Then dicInstalledSku.Add sConfigName,sConfigName
‘Categorize the SKU
‘Three categories are available: ClientSuite, ClientSingleProduct, Server
If RegReadValue(HKLM,REG_ARP&OREGREF&sConfigName,”ProductCodes”,sProductCodeList,”REG_MULTI_SZ”) OR (sConfigName = “CLICK2RUN”) Then
fCategorized = False
If sConfigName = “CLICK2RUN” Then sProductCodeList = “{90″ & OVERSIONMAJOR & “0011-0062-0000-0000-0000000FF1CE}”
For Each sProductCode in Split(sProductCodeList,chr(34))
If Len(sProductCode) = 38 Then
If NOT Mid(sProductCode,11,1) = “0″ Then
‘Server product
If NOT dicSrv.Exists(UCase(sConfigName)) Then dicSrv.Add UCase(sConfigName),sConfigName
fCategorized = True
Exit For
Else
Select Case Mid(sProductCode,11,4)
‘Client Suites
Case “000F”,”0011″,”0012″,”0013″,”0014″,”0015″,”0016″,”0017″,”0018″,”0019″,”001A”,”001B”,”0029″,”002B”,”002E”,”002F”,”0030″,”0031″,”0033″,”0035″,”0037″,”003D”,”0044″,”0049″,”0061″,”0062″,”0066″,”006C”,”006D”,”006F”,”0074″,”00A1″,”00A3″,”00A9″,”00BA”,”00CA”,”00E0″,”0100″,”0103″,”011A”
If NOT dicCSuite.Exists(UCase(sConfigName)) Then dicCSuite.Add UCase(sConfigName),sConfigName
fCategorized = True
Exit For
Case Else
End Select
End If
End If ‘Len 38
Next ‘sProductCode
If NOT fCategorized Then
If NOT dicCSingle.Exists(UCase(sConfigName)) Then dicCSingle.Add UCase(sConfigName),sConfigName
End If ‘fCategorized
End If ‘RegReadValue “ProductCodes”
End If
Next ‘ArpItem
End If ‘RegEnumKey
End Sub ‘FindInstalledOProducts
‘=======================================================================================================
‘Check if there are Office products from previous versions on the computer
Sub CheckForLegacyProducts
Const OLEGACY = “78E1-11D2-B60F-006097C998E7}.6000-11D3-8CFE-0050048383C9}.6000-11D3-8CFE-0150048383C9}.BDCA-11D1-B7AE-00C04FB92F3D}.6D54-11D4-BEE3-00C04F990354}”
Dim Product
‘Set safe default
fLegacyProductFound = True
For Each Product in oMsi.Products
If Len(Product) = 38 Then
‘Handle O09 – O11 Products
If InStr(OLEGACY, UCase(Right(Product, 28)))>0 Then
‘Found legacy Office product. Keep flag in default and exit
Exit Sub
End If
If UCase(Right(Product,PRODLEN))=OFFICEID Then
Select Case Mid(Product,4,2)
Case “12″
If CInt(OVERSIONMAJOR) > 12 Then
‘Found legacy Office product. Keep flag in default and exit
Exit Sub
End If
Case Else
End Select
End If
End If ’38
Next ‘Product
fLegacyProductFound = False
End Sub ‘CheckForLegacyProducts
‘=======================================================================================================
‘Create clean list of Products to remove.
‘Strip off bad & empty contents
Sub ValidateRemoveSkuList
Dim Sku, Key, sProductCode, sProductCodeList
Dim arrRemoveSKUs
If fRemoveAll Then
‘Remove all mode
For Each Key in dicInstalledSku.Keys
dicRemoveSku.Add Key,dicInstalledSku.Item(Key)
Next ‘Key
Else
‘Remove individual products or preconfigured configurations mode
‘Ensure to have a string with no unexpected contents
sSkuRemoveList = Replace(sSkuRemoveList,”;”,”,”)
sSkuRemoveList = Replace(sSkuRemoveList,” “,””)
sSkuRemoveList = Replace(sSkuRemoveList,Chr(34),””)
While InStr(sSkuRemoveList,”,,”)>0
sSkuRemoveList = Replace(sSkuRemoveList,”,,”,”,”)
Wend
‘Prepare ‘remove’ and ‘keep’ dictionaries to determine what has to be removed
‘Initial pre-fill of ‘keep’ dic
For Each Key in dicInstalledSku.Keys
dicKeepSku.Add Key,dicInstalledSku.Item(Key)
Next ‘Key
‘Determine contents of keep and remove dic
‘Individual products
arrRemoveSKUs = Split(UCase(sSkuRemoveList),”,”)
For Each Sku in arrRemoveSKUs
If Sku = “OSE” Then fRemoveOse = True
If Sku = “CLICK2RUN” Then fRemoveC2R = True
If dicKeepSku.Exists(Sku) Then
‘A Sku to remove has been passed in
‘remove the item from the keep dic
dicKeepSku.Remove(Sku)
‘Now add it to the remove dic
If NOT dicRemoveSku.Exists(Sku) Then dicRemoveSku.Add Sku,Sku
End If
Next ‘Sku
‘Client Suite Category
If fRemoveCSuites Then
fRemoveC2R = True
For Each Key in dicInstalledSku.Keys
If dicCSuite.Exists(Key) Then
If dicKeepSku.Exists(Key) Then dicKeepSku.Remove(Key)
If NOT dicRemoveSku.Exists(Key) Then dicRemoveSku.Add Key,Key
End If
Next ‘Key
End If ‘fRemoveCSuites
‘Client Single/Standalone Category
If fRemoveCSingle Then
For Each Key in dicInstalledSku.Keys
If dicCSingle.Exists(Key) Then
If dicKeepSku.Exists(Key) Then dicKeepSku.Remove(Key)
If NOT dicRemoveSku.Exists(Key) Then dicRemoveSku.Add Key,Key
End If
Next ‘Key
End If ‘fRemoveCSingle
‘Server Category
If fRemoveSrv Then
For Each Key in dicInstalledSku.Keys
If dicSrv.Exists(Key) Then
If dicKeepSku.Exists(Key) Then dicKeepSku.Remove(Key)
If NOT dicRemoveSku.Exists(Key) Then dicRemoveSku.Add Key,Key
End If
Next ‘Key
End If ‘fRemoveSrv
If NOT dicKeepSku.Count > 0 Then fRemoveAll = True
End If ‘fRemoveAll
‘Fill the KeepProd dic
For Each Sku in dicKeepSku.Keys
If RegReadValue(HKLM,REG_ARP & OREGREF & Sku,”ProductCodes”,sProductCodeList,”REG_MULTI_SZ”) Then
For Each sProductCode in Split(sProductCodeList,chr(34))
If Len(sProductCode) = 38 Then
If NOT dicKeepProd.Exists(sProductCode) Then dicKeepProd.Add sProductCode,Sku
End If ’38
Next ‘sProductCod
End If
Next ‘Sku
If fRemoveAll OR fRemoveOse Then CheckRemoveOSE
If fRemoveAll OR fRemoveOspp Then CheckRemoveOspp
If fRemoveAll OR fRemoveC2R Then CheckRemoveSG
End Sub ‘ValidateRemoveSkuList
‘=======================================================================================================
‘Check if SoftGrid Client can be scrubbed
Sub CheckRemoveSG
Dim Key
Dim sPKey
Dim arrKeys
If NOT CInt(OVERSIONMAJOR) > 12 Then
fRemoveC2R = False
Exit Sub
End If
If fForce Then
fRemoveAppV = True
Exit Sub
End If
fRemoveAppV = False
If RegEnumKey (HKLM,”SOFTWARE\Microsoft\SoftGrid\4.5\Client\Applications”,arrKeys) Then
For Each Key in arrKeys
If Len(Key)>15 Then
‘Get Partial product Key
sPKey = Right(Key,16)
If Left(sPKey,4) = “90″&OVERSIONMAJOR Then
If NOT GetProductID(Mid(sPKey,5,4)) = “CLICK2RUN” Then Exit Sub
Else
Exit Sub
End If
Else
Exit Sub
End If
Next ‘Key
End If
‘If we got here it’s only Click2Run apps
fRemoveAppV = True
End Sub ‘CheckRemoveSG
‘=======================================================================================================
‘Check if OSE service can be scrubbed
Sub CheckRemoveOSE
Const O11 = “6000-11D3-8CFE-0150048383C9}”
Dim Product
If fRemoveOse Then Exit Sub
For Each Product in oMsi.Products
If Len(Product) = 38 Then
If UCase(Right(Product,28)) = O11 Then
‘Found Office 2003 Product. Set flag to not remove the OSE service
Exit Sub
End If
If UCase(Right(Product,PRODLEN))=OFFICEID Then
Select Case Mid(Product,4,2)
Case “12″,”14″,”15″,”16″,”17″
‘Found another Office product. Set flag to keep the OSE service
If NOT Mid(Product,4,2) = OVERSIONMAJOR Then
fRemoveOse = False
Exit Sub
End If
Case Else
End Select
End If
End If ’38
Next ‘Product
fRemoveOse = True
End Sub ‘CheckRemoveOSE
‘=======================================================================================================
‘Check if OSPP service can be scrubbed
Sub CheckRemoveOSPP
Dim Product
If NOT CInt(OVERSIONMAJOR) > 12 Then
fRemoveOspp = False
Exit Sub
End If
If fRemoveOspp Then Exit Sub
For Each Product in oMsi.Products
If Len(Product) = 38 Then
If UCase(Right(Product,PRODLEN))=OFFICEID Then
Select Case Mid(Product,4,2)
Case “14″,”15″,”16″,”17″
‘Found another Office product. Set flag to keep the OSPP service
If NOT Mid(Product,4,2) = OVERSIONMAJOR Then
fRemoveOspp = False
Exit Sub
End If
Case Else
End Select
End If
End If ’38
Next ‘Product
fRemoveOspp = True
End Sub ‘CheckRemoveOSPP
‘=======================================================================================================
‘Cache .msi files for products that will be removed in case they are needed for later file detection
Sub CacheMsiFiles
Dim Product
Dim sMsiFile
‘Non critical routine for failures.
‘Errors will be logged but must not fail the execution
On Error Resume Next
Log ” Cache .msi files to temporary Scrub folder”
‘Cache the files
For Each Product in oMsi.Products
‘Ensure valid GUID length
If Len(Product) = 38 Then
If (Right(Product,PRODLEN) = OFFICEID AND Mid(Product,4,2)=OVERSIONMAJOR) AND (fRemoveAll OR CheckDelete(Product))Then
CheckError “CacheMsiFiles”
sMsiFile = oMsi.ProductInfo(Product,”LocalPackage”) : CheckError “CacheMsiFiles”
LogOnly ” – ” & Product & “.msi”
If oFso.FileExists(sMsiFile) Then oFso.CopyFile sMsiFile,sScrubDir & “\” & Product & “.msi”,True
CheckError “CacheMsiFiles”
End If ‘Right(Product,PRODLEN) = OFFICEID …
End If ’38
Next ‘Product
Err.Clear
End Sub ‘CacheMsiFiles
‘=======================================================================================================
‘Build a list of all files that will be deleted
Sub ScanComponents
Const MSIOPENDATABASEREADONLY = 0
Const MSIINSTALLSTATE_LOCAL = 3
Dim FileList, RegList, ComponentID, CompClient, Record, qView, MsiDb
Dim Processes, Process, Prop, prod
Dim sQuery, sSubKeyName, sPath, sFile, sMsiFile, sCompClient, sComponent
Dim fRemoveComponent, fAffectedComponent, fIsPermanent
Dim i, iProgress, iCompCnt, iRemCnt
Dim dicFLError, oDic, oFolderDic, dicCompPath
Dim hDefKey
‘Logfile
Set FileList = oFso.OpenTextFile(sScrubDir & “\FileList.txt”,FOR_WRITING,True,True)
Set RegList = oFso.OpenTextFile(sScrubDir & “\RegList.txt”,FOR_WRITING,True,True)
‘FileListError dic
Set dicFLError = CreateObject(“Scripting.Dictionary”)
Set oDic = CreateObject(“Scripting.Dictionary”)
Set oFolderDic = CreateObject(“Scripting.Dictionary”)
Set dicCompPath = CreateObject(“Scripting.Dictionary”)
‘Prevent that API errors fail script execution
On Error Resume Next
iCompCnt = oMsi.Components.Count
If NOT Err = 0 Then
‘API failure
Log “Error during components detection. Cannot complete this task.”
Err.Clear
Exit Sub
End If
‘Ensure to not divide by zero
If iCompCnt = 0 Then iCompCnt = 1
LogOnly ” Scanning ” & iCompCnt & ” components”
‘Enum all Components
For Each ComponentID In oMsi.Components
‘Progress bar
i = i + 1
If iProgress 4 Then
If Left(sPath,1) = “0″ Then
‘Registry keypath
Select Case Left(sPath,2)
Case “00″
sPath = Mid(sPath,5)
hDefKey = HKCR
Case “01″
sPath = Mid(sPath,5)
hDefKey = HKCU
Case “02″
sPath = Mid(sPath,5)
hDefKey = HKLM
Case Else
‘
End Select
If NOT dicDelRegKey.Exists(sPath) Then
dicDelRegKey.Add sPath,hDefKey
RegList.WriteLine HiveString(hDefKey)&”\”&sPath
End If
Else
‘File
If oFso.FileExists(sPath) Then
sPath = oFso.GetFile(sPath).ParentFolder
If Not oFolderDic.Exists(sPath) Then oFolderDic.Add sPath,sPath
‘Get the .msi file
If oFso.FileExists(sScrubDir & “\” & sCompClient & “.msi”) Then
sMsiFile = sScrubDir & “\” & sCompClient & “.msi”
Else
sMsiFile = oMsi.ProductInfo(sCompClient,”LocalPackage”)
End If
If Not Err = 0 Then
If NOT dicFLError.Exists(“Failed to obtain .msi file for product “&sCompClient) Then _
dicFLError.Add “Failed to obtain .msi file for product “&sCompClient, ComponentID
Err.Clear
End If
Set MsiDb = oMsi.OpenDatabase(sMsiFile,MSIOPENDATABASEREADONLY)
If Err = 0 Then
‘Get the component name from the ‘Component’ table
sQuery = “SELECT `Component`,`ComponentId` FROM Component WHERE `ComponentId` = ‘” & ComponentID &”‘”
Set qView = MsiDb.OpenView(sQuery) : qView.Execute
Set Record = qView.Fetch()
If Not Record Is Nothing Then sComponent = Record.Stringdata(1)
‘Get filenames from the ‘File’ table
sQuery = “SELECT `Component_`,`FileName` FROM File WHERE `Component_` = ‘” & sComponent &”‘”
Set qView = MsiDb.OpenView(sQuery) : qView.Execute
Set Record = qView.Fetch()
Do Until Record Is Nothing
‘Read the filename
sFile = Record.StringData(2)
If InStr(sFile,”|”) > 0 Then sFile = Mid(sFile,InStr(sFile,”|”)+1,Len(sFile))
‘sFile = sPath & “\” & sFile
If Not oDic.Exists(sPath & “\” & sFile) Then
‘Exception handler
fAdd = True
Select Case UCase(sFile)
Case “FPERSON.DLL”
‘Catch exception caused by changed .msi keypath authoring logic for smart tags
For Each prod in oMsi.Products
If NOT Checkdelete(prod) Then
If oMsi.FeatureState(prod, “MSTagPluginNamesFiles”) = MSIINSTALLSTATE_LOCAL Then
fAdd = False
Exit For
End If
End If
Next ‘prod
Case Else
End Select
If fAdd Then
oDic.Add sPath & “\” & sFile,sFile
FileList.WriteLine sFile
If Len(sFile)>4 Then
sFile = LCase(sFile)
If Right(sFile,4) = “.exe” Then
If NOT dicApps.Exists(sFile) Then
Select Case sFile
Case “setup.exe”,”ose.exe”,”osppsvc.exe”,”explorer.exe”,”cvhsvc.exe”,”sftvsa.exe”,”sftlist.exe”,”sftplay.exe”,”sftvol.exe”,”sftfs.exe”
Case Else
dicApps.Add sFile,LCase(sPath) & “\” & sFile
End Select
End If ‘dicApps.Exists
End If ‘.exe
End If ‘Len > 4
End If ‘fAdd
End If ‘oDic.Exists
Set Record = qView.Fetch()
Loop
Set Record = Nothing
qView.Close
Set qView = Nothing
Else
If NOT dicFLError.Exists(“Error: Could not read from .msi file: “&sMsiFile) Then _
dicFLError.Add “Error: Could not read from .msi file: “&sMsiFile, ComponentID
Err.Clear
End If ‘Err = 0
End If ‘FileExists(sPath)
End If
End If ‘Len(sPath) > 4
Else
‘Add the path to the ‘Keep’ dictionary
Err.Clear
For Each CompClient In oMsi.ComponentClients(ComponentID)
‘Get the component path
sPath = “” : sPath = LCase(oMsi.ComponentPath(CompClient,ComponentID))
sPath = Replace(sPath,”?”,”:”)
If Len(sPath) > 4 Then
If Left(sPath,1) = “0″ Then
‘Registry keypath
Select Case Left(sPath,2)
Case “00″
sPath = Mid(sPath,5)
hDefKey = HKCR
Case “01″
sPath = Mid(sPath,5)
hDefKey = HKCU
Case “02″
sPath = Mid(sPath,5)
hDefKey = HKLM
Case Else
‘
End Select
If NOT dicKeepReg.Exists(sPath) Then
dicKeepReg.Add sPath,hDefKey
End If
Else
‘File keypath
If oFso.FileExists(sPath) Then
sPath = LCase(oFso.GetFile(sPath).ParentFolder)
If Not dicKeepFolder.Exists(sPath) Then AddKeepFolder sPath
End If
End If ‘Is Registry
End If ‘sPath > 4
Next ‘CompClient
End If ‘fRemoveComponent
Next ‘ComponentID
Err.Clear
On Error Goto 0
‘Click2Run detection
If C2RInstalled Then
‘Add executables that might need to be closed
If NOT dicApps.Exists(“cvh.exe”) Then dicApps.Add “cvh.exe”,”cvh.exe”
If NOT dicApps.Exists(“officevirt.exe”) Then dicApps.Add “officevirt.exe”,”officevirt.exe”
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Process”)
For Each Process in Processes
For Each Prop in Process.Properties_
If Prop.Name = “ExecutablePath” Then
If Len(Prop.Value) > 2 Then
If UCase(Left(Prop.Value,2)) = “Q:” Then
If NOT dicApps.Exists(LCase(Process.Name)) Then dicApps.Add LCase(Process.Name),Process.Name
End If ‘Q:
End If ‘>2
End If ‘ExcecutablePath
Next ‘Prop
Next ‘Process
End If ‘C2RInstalled
Log ” Done”
If dicFLError.Count > 0 Then LogOnly Join(dicFLError.Keys,vbCrLf)
If Not oFolderDic.Count = 0 Then arrDeleteFolders = oFolderDic.Keys Else Set arrDeleteFolders = Nothing
If Not oDic.Count = 0 Then arrDeleteFiles = oDic.Keys Else Set arrDeleteFiles = Nothing
End Sub ‘ScanComponents
‘=======================================================================================================
‘Detect if Click2Run products are installed on the client
Function C2RInstalled
Dim Key, sPKey, sValue, VProd
Dim arrKeys
If RegEnumKey (HKLM,REG_ARP,arrKeys) Then
For Each Key in arrKeys
If Len(Key)=38 Then
If UCase(Right(Key,PRODLEN))=OFFICEID AND Mid(Key,4,2)=OVERSIONMAJOR Then
If RegReadValue(HKLM,REG_ARP&”\”&Key,”CVH”,sValue,”REG_DWORD”) Then
If sValue = “1″ Then
C2RInstalled = True
Exit Function
End If
End If
End If
End If
Next ‘Key
End If
If RegEnumKey (HKLM,”SOFTWARE\Microsoft\SoftGrid\4.5\Client\Applications”,arrKeys) Then
For Each Key in arrKeys
If Len(Key)>15 Then
‘Get Partial product Key
sPKey = Right(Key,16)
If Left(sPKey,4) = “90″ & OVERSIONMAJOR Then
If GetProductID(Mid(sPKey,5,4)) = “CLICK2RUN” Then
C2RInstalled = True
Exit Function
End If
End If
End If
Next ‘Key
End If
End Function ‘C2RInstalled
‘=======================================================================================================
‘Try to remove the products by calling setup.exe
Sub SetupExeRemoval
Dim OseService, Service, TextStream
Dim iSetupCnt, RetVal
Dim Sku, sConfigFile, sUninstallCmd, sCatalyst, sCVHBS, sDll, sDisplayLevel, sNoCancel
iSetupCnt = 0
If Not dicRemoveSku.Count > 0 Then
Log ” Nothing to remove for Setup.exe”
Exit Sub
End If
For Each Sku in dicRemoveSku.Keys
If Sku=”CLICK2RUN” Then
‘Reset Softgrid
ResetSG
If f64 Then
sCVHBS = sCommonProgramFilesX86 & “\Microsoft Shared\Virtualization Handler\CVHBS.exe”
Else
sCVHBS = sCommonProgramFiles & “\Microsoft Shared\Virtualization Handler\CVHBS.exe”
End If
If oFso.FileExists(sCVHBS) Then
CvhbsDialogHandler
sUninstallCmd = Chr(34) & sCVHBS & Chr(34) & ” /removesilent”
iSetupCnt = iSetupCnt + 1
Log ” – Calling CVHBS.exe to remove ” & Sku
If Not fDetectOnly Then
On Error Resume Next
RetVal = oWShell.Run(sUninstallCmd,0,True) : CheckError “CVHBSRemoval”
fRebootRequired = True
Log ” – CVHBS.exe returned: ” & SetupExeRetVal(Retval) & ” (” & RetVal & “)” & vbCrLf
On Error Goto 0
Else
Log ” -> Removal suppressed in preview mode.”
End If
Else
Log “Error: Office Click-to-Run CVHBS.exe appears to be missing”
End If ‘oFso.FileExists
‘Make sure that C2R keys are gone to unblock the msiexec task
End If ‘Sku = Click2run
Next ‘Sku
‘Ensure that the OSE service is *installed, *not disabled, *running under System context.
‘If validation fails exit out of this sub.
Set OseService = oWmiLocal.Execquery(“Select * From Win32_Service Where Name like ‘ose%’”)
If OseService.Count = 0 Then Exit Sub
For Each Service in OseService
If (Service.StartMode = “Disabled”) AND (Not Service.ChangeStartMode(“Manual”)=0) Then Exit Sub
If (Not Service.StartName = “LocalSystem”) AND (Service.Change( , , , , , , “LocalSystem”, “”)) Then Exit Sub
Next ‘Service
For Each Sku in dicRemoveSku.Keys
If Sku=”CLICK2RUN” Then
‘Already done
Else
‘Create an “unattended” config.xml file for uninstall
If fQuiet Then sDisplayLevel = “None” Else sDisplayLevel=”Basic”
If fNoCancel Then sNoCancel=”Yes” Else sNoCancel=”No”
Set TextStream = oFso.OpenTextFile(sScrubDir & “\config.xml”,FOR_WRITING,True,True)
TextStream.Writeline “”
TextStream.Writeline “”
TextStream.Writeline “”
TextStream.Writeline “”
TextStream.Writeline “”
TextStream.Close
Set TextStream = Nothing
‘Ensure path to setup.exe is valid to prevent errors
sDll = “”
If RegReadValue(HKLM,REG_ARP & OREGREF & Sku,”UninstallString”,sCatalyst,”REG_SZ”) Then
If InStr(LCase(sCatalyst),”/dll”)>0 Then sDll = Right(sCatalyst,Len(sCatalyst)-InStr(LCase(sCatalyst),”/dll”)+2)
If InStr(sCatalyst,”/”)>0 Then sCatalyst = Left(sCatalyst,InStr(sCatalyst,”/”)-1)
sCatalyst = Trim(Replace(sCatalyst,Chr(34),””))
If NOT oFso.FileExists(sCatalyst) Then
sCatalyst = sCommonProgramFiles & “\” & OREF & “\Office Setup Controller\setup.exe”
If NOT oFso.FileExists(sCatalyst) AND f64 Then
sCatalyst = sCommonProgramFilesX86 & “” & OREF & “\Office Setup Controller\setup.exe”
End If
End If
If oFso.FileExists(sCatalyst) Then
sUninstallCmd = Chr(34) & sCatalyst & Chr(34) & ” /uninstall ” & Sku & ” /config ” & Chr(34) & sScrubDir & “\config.xml” & Chr(34) & sDll
iSetupCnt = iSetupCnt + 1
Log ” – Calling Setup.exe to remove ” & Sku ‘& vbCrLf & sUninstallCmd
If Not fDetectOnly Then
On Error Resume Next
RetVal = oWShell.Run(sUninstallCmd,0,True) : CheckError “SetupExeRemoval”
Log ” – Setup.exe returned: ” & SetupExeRetVal(Retval) & ” (” & RetVal & “)” & vbCrLf
fRebootRequired = fRebootRequired OR (RetVal = “3010″)
On Error Goto 0
Else
Log ” -> Removal suppressed in preview mode.”
End If
Else
Log ” Error: Office setup.exe appears to be missing”
End If ‘RetVal = 0) AND oFso.FileExists
End If ‘RegReadValue
End If ‘C2R
Next ‘Sku
If iSetupCnt = 0 Then Log ” Nothing to remove for setup.”
End Sub ‘SetupExeRemoval
‘=======================================================================================================
‘Invoke msiexec to remove individual .MSI packages
Sub MsiexecRemoval
Dim Product
Dim i
Dim sCmd, sReturn
‘Clear up ARP first to avoid possible custom action dependencies
RegWipeARP
‘Check MSI registered products
‘Office System does only support per machine installation so it’s sufficient to use Installer.Products
i = 0
For Each Product in oMsi.Products
If Len(Product) = 38 Then
If (Right(Product,PRODLEN) = OFFICEID AND Mid(Product,4,2)=OVERSIONMAJOR) Then
If fRemoveAll OR CheckDelete(Product) Then
i = i + 1
Log ” Calling msiexec.exe to remove ” & Product
sCmd = “msiexec.exe /x” & Product & ” REBOOT=ReallySuppress NOREMOVESPAWN=True”
If Mid(Product,11,3)=”006″ Then
‘Need to clear out C2R registration first
RegWipeC2R
End If
If fQuiet Then
sCmd = sCmd & ” /q”
Else
sCmd = sCmd & ” /qb-”
End If
sCmd = sCmd & ” /l*v+ “&chr(34)&sLogDir&”\Uninstall_”&Product&”.log”&chr(34)
If NOT fDetectOnly Then
Log ” – Calling msiexec with ‘”&sCmd&”‘”
‘Execute the patch uninstall
sReturn = oWShell.Run(sCmd, 0, True)
Log ” – msiexec returned: ” & SetupExeRetVal(sReturn) & ” (” & sReturn & “)” & vbCrLf
fRebootRequired = fRebootRequired OR (sReturn = “3010″)
Else
Log ” -> Removal suppressed in preview mode. Command: “&sCmd
End If
End If ‘CheckDelete
End If ‘OFFICEID
End If ’38
Next ‘Product
If i = 0 Then Log ” Nothing to remove for msiexec”
End Sub ‘MsiexecRemoval
‘=======================================================================================================
‘Remove the OSE (Office Source Engine) service
Sub RemoveOSE
On Error Resume Next
Log ” OSE CleanUp”
DeleteService “ose”
‘Delete the folder
DeleteFolder sCommonProgramFiles & “\Microsoft Shared\Source Engine”
‘Delete the registration
RegDeleteKey HKLM,”SYSTEM\CurrentControlSet\Services\ose”
End Sub ‘RemoveOSE
‘=======================================================================================================
‘Remove the Softgrid services (App-V and Click2Run)
Sub RemoveSG
On Error Resume Next
Log ” Softgrid CleanUp”
DeleteService(“cvhsvc”)
DeleteService(“SftList”)
DeleteService(“SftPlay”)
DeleteService(“SftVol”)
DeleteService(“SftFs”)
DeleteService(“SftVsa”)
‘Delete the folder
DeleteFolder sAppdata & “\SoftGrid Client”
DeleteFolder sLocalAppData & “\SoftGrid Client”
DeleteFolder sProgramData & “\Microsoft\Application Virtualization Client\SoftGrid Client”
DeleteFolder sProgramData & “\Microsoft\Application Virtualization Client”
DeleteFolder sProgramfiles & “\Microsoft\Microsoft Application Virtualization Client”
DeleteFolder sProgramfiles & “\Microsoft Application Virtualization Client”
‘Delete the registration
RegDeleteKey HKLM,”SYSTEM\CurrentControlSet\Services\cvhsvc”
RegDeleteKey HKLM,”SYSTEM\CurrentControlSet\Services\sftfs”
RegDeleteKey HKLM,”SYSTEM\CurrentControlSet\Services\sftlist”
RegDeleteKey HKLM,”SYSTEM\CurrentControlSet\Services\sftplay”
RegDeleteKey HKLM,”SYSTEM\CurrentControlSet\Services\sftredir”
RegDeleteKey HKLM,”SYSTEM\CurrentControlSet\Services\sftvol”
RegDeleteKey HKLM,”SYSTEM\CurrentControlSet\Services\sftvsa”
RegDeleteKey HKLM,”SYSTEM\CurrentControlSet\Services\sftfs”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\SoftGrid\4.5″
RegDeleteKey HKCU,”Software\Microsoft\SoftGrid\4.5\Client\AppFS”
RegDeleteKey HKCU,”Software\Microsoft\SoftGrid\4.5\Client\Applications”
RegDeleteKey HKCU,”Software\Microsoft\SoftGrid\4.5\Client\FileExtensions”
RegDeleteKey HKCU,”Software\Microsoft\SoftGrid\4.5\Client\FileTypes”
RegDeleteKey HKCU,”Software\Microsoft\SoftGrid\4.5\Client\UserInfo”
‘C2R places custom permissions on these regkeys which prevent them from getting deleted
‘RegDeleteKey HKCU,”Software\Microsoft\SoftGrid\4.5\Client\Network”
‘RegDeleteKey HKCU,”Software\Microsoft\SoftGrid\4.5\Client\Packages”
‘RegDeleteKey HKCU,”Software\Microsoft\SoftGrid\4.5\Client”
‘RegDeleteKey HKCU,”Software\Microsoft\SoftGrid\4.5″
End Sub ‘RemoveSG
‘=======================================================================================================
‘Stops all Softgrid services and virtual applications
Sub ResetSG
Dim Processes, Process
Dim fWait
Dim iRet
On Error Resume Next
fWait = False
Log ” Doing Action: ResetSG”
‘Close all running (virtualized) Office applications
‘OfficeVirt.exe needs to be shut down first
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Process Where Name like ‘officevirt%.exe’”)
For Each Process in Processes
Log ” – End process ” & Process.Name
iRet = Process.Terminate()
CheckError “ResetSG: ” & “Process.Name”
fWait = True
Next ‘Process
‘Shut down CVH.exe
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Process Where Name=’cvh.exe’”)
For Each Process in Processes
Log ” – End process ” & Process.Name
iRet = Process.Terminate()
CheckError “ResetSG: ” & “Process.Name”
Next ‘Process
‘Close running instances
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Process”)
For Each Process in Processes
If dicApps.Exists(LCase(Process.Name)) Then
Log ” – End process ” & Process.Name
iRet = Process.Terminate()
CheckError “CloseOfficeApps: ” & “Process.Name”
End If
Next ‘Process
If fWait Then wscript.sleep 10000
‘Stop all SoftGrid services
iRet = StopService(“cvhsvc”)
iRet = StopService(“SftList”)
iRet = StopService(“SftPlay”)
iRet = StopService(“SftVol”)
iRet = StopService(“SftFs”)
iRet = StopService(“SftVsa”)
End Sub ‘ResetSG
‘=======================================================================================================
‘File cleanup operations for the Local Installation Source (MSOCache)
Sub WipeLIS
Const LISROOT = “MSOCache\All Users\”
Dim LogicalDisks, Disk, Folder, SubFolder, MseFolder, File, Files
Dim arrSubFolders
Dim sFolder
Dim fRemoveFolder
Log ” LIS CleanUp”
‘Search all hard disks
Set LogicalDisks = oWmiLocal.ExecQuery(“Select * From Win32_LogicalDisk WHERE DriveType=3″)
For Each Disk in LogicalDisks
If oFso.FolderExists(Disk.DeviceID & “\” & LISROOT)Then
Set Folder = oFso.GetFolder(Disk.DeviceID & “\” & LISROOT)
For Each Subfolder in Folder.Subfolders
If Len(Subfolder) > 37 Then
If fRemoveAll Then
If (Mid(Subfolder.Name,26,PRODLEN) = OFFICEID AND Mid(SubFolder.Name,4,2)=OVERSIONMAJOR) OR _
LCase(Right(Subfolder.Name,7)) = OVERSIONMAJOR &”.data” Then DeleteFolder Subfolder.Path
Else
If (Mid(Subfolder.Name,26,PRODLEN) = OFFICEID AND Mid(SubFolder.Name,4,2)=OVERSIONMAJOR) AND _
CheckDelete(UCase(Left(Subfolder.Name,38))) AND _
UCase(Right(Subfolder,1))= UCase(Left(Disk.DeviceID,1))Then DeleteFolder Subfolder.Path
End If
End If ‘Len > 37
Next ‘Subfolder
If (Folder.Subfolders.Count = 0) AND (Folder.Files.Count = 0) Then
sFolder = Folder.Path
Set Folder = Nothing
SmartDeleteFolder sFolder
End If
End If ‘oFso.FolderExists
Next ‘Disk
‘MSECache
If EnumFolders(sProgramFiles,arrSubFolders) Then
For Each SubFolder in arrSubFolders
If UCase(Right(SubFolder,9))=”\MSECACHE” Then
ReDim arrMseFolders(-1)
Set Folder = oFso.GetFolder(SubFolder)
GetMseFolderStructure Folder
For Each MseFolder in arrMseFolders
If oFso.FolderExists(MseFolder) Then
fRemoveFolder = False
Set Folder = oFso.GetFolder(MseFolder)
Set Files = Folder.Files
For Each File in Files
If (LCase(Right(File.Name,4))=”.msi”) Then
If CheckDelete(ProductCode(File.Path)) Then
fRemoveFolder = True
Exit For
End If ‘CheckDelete
End If
Next ‘File
Set Files = Nothing
Set Folder = Nothing
If fRemoveFolder Then SmartDeleteFolder MseFolder
End If ‘oFso.FolderExists(MseFolder)
Next ‘MseFolder
End If
Next ‘SubFolder
End If ‘oFso.FolderExists
End Sub ‘WipeLis
‘=======================================================================================================
‘Wipe files and folders as documented in KB 928218
Sub FileWipeAll
Dim sFolder
Dim Folder, Subfolder
If fForce OR fQuiet Then CloseOfficeApps
‘Handle other services.
Select Case OVERSIONMAJOR
Case “12″
Case “14″
DeleteService “odserv”
DeleteService “Microsoft Office Groove Audit Service”
DeleteService “Microsoft SharePoint Workspace Audit Service”
Case Else
End Select
‘User specific files
If NOT fKeepUser Then
‘Delete files that should be backed up before deleting them
CopyAndDeleteFile sAppdata & “\Microsoft\Templates\Normal.dotm”
CopyAndDeleteFile sAppdata & “\Microsoft\Templates\Normalemail.dotm”
sFolder = sAppdata & “\microsoft\document building blocks”
If oFso.FolderExists(sFolder) Then
Set Folder = oFso.GetFolder(sFolder)
For Each Subfolder In Folder.Subfolders
If oFso.FileExists(Subfolder & “\blocks.dotx”) Then CopyAndDeleteFile Subfolder & “\blocks.dotx”
Next ‘Subfolder
Set Folder = Nothing
End If ‘oFso.FolderExists(sFolder)
End If
‘Run the individual filewipe from component detection first
FileWipeIndividual
‘Take care of the rest
DeleteFolder sOInstallRoot
DeleteFolder sCommonProgramFiles & “\Microsoft Shared\” & OREF
DeleteFile sAllUsersProfile & “\Application Data\Microsoft\Office\Data\opa”&OVERSIONMAJOR&”.dat”
DeleteFile sAllUsersProfile & “\Microsoft\Office\Data\opa”&OVERSIONMAJOR&”.dat”
If (fRemoveOspp OR fForce) AND CInt(OVERSIONMAJOR)>12 Then
DeleteService “osppsvc”
DeleteFolder sCommonProgramFiles & “\Microsoft Shared\OfficeSoftwareProtectionPlatform”
DeleteFolder sAllUsersProfile & “\Microsoft\OfficeSoftwareProtectionPlatform”
End If
Select Case OVERSIONMAJOR
Case “12″
Case “14″
DeleteFile oWShell.SpecialFolders(“AllUsersStartup”)&”\OfficeSAS.lnk”
DeleteFile oWShell.SpecialFolders(“Startup”)&”\OneNote 2010 Screen Clipper and Launcher.lnk”
Case Else
End Select
End Sub ‘FileWipeAll
‘=======================================================================================================
‘Wipe individual files & folders related to SKU’s that are no longer installed
Sub FileWipeIndividual
Dim LogicalDisks, Disk
Dim File, Files, XmlFile, scFiles, oFile, Folder, SubFolder, Processes, Process
Dim sFile, sFolder, sPath, sConfigName, sContents, sProductCode, sLocalDrives,sScQuery
Dim arrSubfolders
Dim fKeepFolder, fDeleteSC
Dim iRet
Log ” File CleanUp”
If IsArray(arrDeleteFiles) Then
If fForce OR fQuiet Then
Log ” Doing Action: StopOSE”
iRet = StopService(“ose”)
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Service Where Name like ‘ose%.exe’”)
For Each Process in Processes
LogOnly ” – Running process : ” & Process.Name
Log ” -> Ending process: ” & Process.Name
iRet = Process.Terminate()
Next ‘Process
LogOnly ” End Action: StopOSE”
CloseOfficeApps
End If
‘Wipe individual files detected earlier
LogOnly ” Removing left behind files”
For Each sFile in arrDeleteFiles
If oFso.FileExists(sFile) Then DeleteFile sFile
Next ‘File
End If ‘IsArray
‘Wipe Catalyst in commonfiles
sFolder = sCommonProgramFiles & “\microsoft shared\”&OREF&”\Office Setup Controller\”
If EnumFolderNames(sFolder,arrSubFolders) Then
For Each SubFolder in arrSubFolders
sPath = sFolder & SubFolder
If InStr(SubFolder,”.”)>0 Then sConfigName = UCase(Left(SubFolder,InStr(SubFolder,”.”)-1))Else sConfigName = UCase(Subfolder)
If GetFolderPath(sPath) Then
Set Folder = oFso.GetFolder(sPath)
Set Files = Folder.Files
fKeepFolder = False
For Each File In Files
If Len(File.Name)>3 Then
If (LCase(Right(File.Name,4))=”.xml”) Then
If Len(File.Name) >= Len(sConfigName) Then
If (UCase(Left(File.Name,Len(sConfigName)))=sConfigName) Then
Set XmlFile = oFso.OpenTextFile(File,1)
sContents = XmlFile.ReadAll
Set XmlFile = Nothing
sProductCode = “”
On Error Resume Next
sProductCode = Mid(sContents,InStr(sContents,”ProductCode=”)+Len(“ProductCode=”)+1,38)
On Error Goto 0
If Len(sProductCode) = 38 Then
If CheckDelete(sProductCode) Then DeleteFile File.Path Else fKeepFolder = True
End If
End If ‘sConfigName
End If ‘Len >=
End If ‘.xml
End If ‘Len(File.Name)>3
Next ‘File
Set Files = Nothing
Set Folder = Nothing
If Not fKeepFolder Then DeleteFolder sPath
End If ‘GetFolderPath
Next ‘SubFolder
End If ‘EnumFolderNames
‘Wipe Shortcuts from local hard disks
If NOT fSkipSD Then
On Error Resume Next
Log ” Searching for shortcuts. This can take some time …”
Set LogicalDisks = oWmiLocal.ExecQuery(“Select * From Win32_LogicalDisk WHERE DriveType=3″)
For Each Disk in LogicalDisks
sLocalDrives = sLocalDrives & UCase(Disk.DeviceID) & “\;”
sScQuery = “Select * From Win32_ShortcutFile WHERE Drive=’”&Disk.DeviceID&”‘”
Set scFiles = oWmiLocal.ExecQuery(sScQuery)
For Each File in scFiles
fDeleteSC = False
‘Compare if the shortcut target is in the list of executables that will be removed
If Len(File.Target)>0 Then
For Each item in dicApps.Items
If LCase(File.Target) = item Then
fDeleteSC = True
Exit For
End If
Next ‘item
End If
‘Handle Windows Installer shortcuts
If InStr(File.Target,”{“)>0 Then
If Len(File.Target)>=InStr(File.Target,”{“)+37 Then
If CheckDelete(Mid(File.Target,InStr(File.Target,”{“),38)) Then fDeleteSC = True
End If
End If
‘Handle C2R
If InStr(File.Target,”CVH.EXE”)>0 AND (fRemoveAll OR fRemoveC2R) Then
If InStr(File.Target,”90″ & OVERSIONMAJOR & “006″)>0 Then fDeleteSC = True
End If
If fDeleteSC Then
If Not IsArray(arrDeleteFolders) Then ReDim arrDeleteFolders(0)
sFolder = Left(File.Description,InStrRev(File.Description,”\”)-1)
If Not arrDeleteFolders(UBound(arrDeleteFolders)) = sFolder Then
ReDim Preserve arrDeleteFolders(UBound(arrDeleteFolders)+1)
arrDeleteFolders(UBound(arrDeleteFolders)) = sFolder
End If
DeleteFile File.Description
End If ‘fDeleteSC
Next ‘scFile
Next
On Error Goto 0
End If ‘NOT SkipSD
Err.Clear
End Sub ‘FileWipeIndividual
‘=======================================================================================================
Sub DelScrubTmp
On Error Resume Next
If oFso.FileExists(sScrubDir&”\CvhbsQuiet.vbs”) Then oFso.DeleteFile sScrubDir&”\CvhbsQuiet.vbs”,True
If oFso.FolderExists(sScrubDir & “\ScrubTmp”) Then oFso.DeleteFolder sScrubDir & “\ScrubTmp”,True
End Sub ‘DelScrubTmp
‘=======================================================================================================
‘Ensure there are no unexpected .msi files in the scrub folder
Sub DeleteMsiScrubCache
Dim Folder, File, Files
Log ” ScrubCache CleanUp”
Set Folder = oFso.GetFolder(sScrubDir) : CheckError “DeleteMsiScrubCache”
Set Files = Folder.Files
For Each File in Files
CheckError “DeleteMsiScrubCache”
If LCase(Right(File.Name,4))=”.msi” Then
CheckError “DeleteMsiScrubCache”
DeleteFile File.Path : CheckError “DeleteMsiScrubCache”
End If
Next ‘File
End Sub ‘DeleteMsiScrubCache
‘=======================================================================================================
Sub MsiClearOrphanedFiles
Const USERSIDEVERYONE = “s-1-1-0″
Const MSIINSTALLCONTEXT_ALL = 7
Const MSIPATCHSTATE_ALL = 15
On Error Resume Next
Dim Patch, AllPatches, Product, AllProducts
Dim File, Files, Folder
Dim sFName, sLocalMsp, sLocalMsi, sPatchList, sMsiList
Set Folder = oFso.GetFolder(sWinDir & “\Installer”)
Set Files = Folder.Files
Log ” Windows Installer cache CleanUp”
‘Get a complete list of patches
Err.Clear
Set AllPatches = oMsi.PatchesEx(“”,USERSIDEVERYONE,MSIINSTALLCONTEXT_ALL,MSIPATCHSTATE_ALL)
If Err 0 Then
CheckError “MsiClearOrphanedFiles (msp)”
Else
‘Fill a comma separated stringlist with all .msp patchfiles
For Each Patch in AllPatches
sLocalMsp = “” : sLocalMsp = LCase(Patch.Patchproperty(“LocalPackage”)) : CheckError “MsiClearOrphanedFiles (msp)”
sPatchList = sPatchList & sLocalMsp & “,”
Next ‘Patch
‘Delete all non referenced .msp files from %windir%\installer
For Each File in Files
sFName = “” : sFName = LCase(File.Path)
If LCase(Right(sFName,4)) = “.msp” Then
If Not InStr(sPatchList,sFName) > 0 Then
‘While this is an orphaned file keep the scope of Office only
If InStr(UCase(MspTargets(File.Path)),OFFICEID)>0 Then DeleteFile File.Path
End If
End If ‘LCase(Right(sFName,4))
Next ‘File
End If ‘Err=0
‘Get a complete list products
Err.Clear
Set AllProducts = oMsi.ProductsEx(“”,USERSIDEVERYONE,MSIINSTALLCONTEXT_ALL)
If Err 0 Then
CheckError “MsiClearOrphanedFiles (msi)”
Else
‘Fill a comma separated stringlist with all .msi files
For Each Product in AllProducts
sLocalMsi = “” : sLocalMsi = LCase(Product.InstallProperty(“LocalPackage”)) : CheckError “MsiClearOrphanedFiles (msi)”
sMsiList = sMsiList & sLocalMsi & “,”
Next ‘Product
‘Delete all non referenced .msi files from %windir%\installer
For Each File in Files
sFName = “” : sFName = LCase(File.Path)
If LCase(Right(sFName,4)) = “.msi” Then
If Not InStr(sMsiList,sFName) > 0 Then
‘While this is an orphaned file keep the scope of Office only
If UCase(Right(ProductCode(File.Path),PRODLEN))=OFFICEID Then DeleteFile File.Path
End If
End If ‘LCase(Right(sFName,4)) = “.msi”
Next ‘File
End If ‘Err=0
End Sub ‘MsiClearOrphanedFiles
‘=======================================================================================================
Sub RegWipe
Dim Item, Name, Sku, key
Dim hDefKey, sSubKeyName, sCurKey, sValue, sGuid
Dim fkeep, fSystemComponent0, fPackages, fDisplayVersion
Dim arrKeys, arrNames, arrTypes
Dim iLoopCnt, iPos
Log ” Registry CleanUp”
‘Wipe registry data
‘User Profile settings
RegDeleteKey HKCU,”Software\Policies\Microsoft\Office\” & OVERSION
If NOT fKeepUser Then
RegDeleteKey HKCU,”Software\Microsoft\Office\” & OVERSION
End If ‘fKeepUser
‘Computer specific settings
If fRemoveAll Then
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Office\” & OVERSION
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Office Test”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Office\Common”,”LastAccessInstall”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Office\Common”,”MID”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Office\Common\OffDiag\Location”,OVERSIONMAJOR
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Office\Excel\Addins\Microsoft.PerformancePoint.Planning.Client.Excel”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Office\InfoPath\Converters\Import\InfoPath.DesignerExcelImport\Versions”,OVERSION
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Office\InfoPath\Converters\Import\InfoPath.DesignerWordImport\Versions”,OVERSION
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Office\Outlook”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Shared Tools\Text Converters\Export\MEWord12″
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Shared Tools\Text Converters\Export\Word12″
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Shared Tools\Text Converters\Export\Word97″
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\MEWord12″
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\Word12″
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\Word97″
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Office\” & OVERSION
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Office\Common\OffDiag\Location”,OVERSIONMAJOR
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Run”,”GrooveMonitor”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Run”,”LobiServer”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Run”,”BCSSync”
RegDeleteKey HKLM,”SYSTEM\CurrentControlSet\Services\Outlook”
Select Case OVERSIONMAJOR
Case “12″
Case “14″
RegDeleteKey HKLM,”SOFTWARE\Microsoft\OfficeSoftwareProtectionPlatform”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\OfficeSoftwareProtectionPlatform_Test”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Office\Common\ActiveX Compatibility\{00024512-0000-0000-C000-000000000046}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Office\OneNote\Adapters”,”{456B0D0E-49DD-4C95-8DB6-175F54DE69A3}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{42042206-2D85-11D3-8CFF-005004838597}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{993BE281-6695-4BA5-8A2A-7AACBFAAB69E}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{0006F045-0000-0000-C000-000000000046}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{C41662BB-1FA0-4CE0-8DC5-9B7F8279FF97}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{7CCA70DB-DE7A-4FB7-9B2B-52E2335A3B5A}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{506F4668-F13E-4AA1-BB04-B43203AB3CC0}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{D66DC78C-4F61-447F-942B-3FB6980118CF}”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\{B4F3A835-0E21-4959-BA22-42B3008E02FF}”
‘Groove Extensions
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks”,”{B5A7F190-DDA6-4420-B3BA-52453494E6CD}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{99FD978C-D287-4F50-827F-B2C658EDA8E7}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{AB5C5600-7E6E-4B06-9197-9ECEF74D31CC}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{920E6DB1-9907-4370-B3A0-BAFC03D81399}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{16F3DD56-1AF5-4347-846D-7C10C4192619}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{2916C86E-86A6-43FE-8112-43ABE6BF8DCC}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{72853161-30C5-4D22-B7F9-0BBC1D38A37E}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{6C467336-8281-4E60-8204-430CED96822D}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{2A541AE1-5BF6-4665-A8A3-CFA9672E4291}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{B5A7F190-DDA6-4420-B3BA-52453494E6CD}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{A449600E-1DC6-4232-B948-9BD794D62056}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{3D60EDA7-9AB4-4DA8-864C-D9B5F2E7281D}”
RegDeleteValue HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved”,”{387E725D-DC16-4D76-B310-2C93ED4752A0}”
RegDeleteKey HKLM,”SOFTWARE\Classes\*\shellex\ContextMenuHandlers\XXX Groove GFS Context Menu Handler XXX”
RegDeleteKey HKLM,”SOFTWARE\Classes\AllFilesystemObjects\shellex\ContextMenuHandlers\XXX Groove GFS Context Menu Handler XXX”
RegDeleteKey HKLM,”SOFTWARE\Classes\Directory\shellex\ContextMenuHandlers\XXX Groove GFS Context Menu Handler XXX”
RegDeleteKey HKLM,”SOFTWARE\Classes\Folder\ShellEx\ContextMenuHandlers\XXX Groove GFS Context Menu Handler XXX”
RegDeleteKey HKLM,”SOFTWARE\Classes\Directory\Background\shellex\ContextMenuHandlers\XXX Groove GFS Context Menu Handler XXX”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\Groove Explorer Icon Overlay 1 (GFS Unread Stub)”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\Groove Explorer Icon Overlay 2 (GFS Stub)”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\Groove Explorer Icon Overlay 2.5 (GFS Unread Folder)”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\Groove Explorer Icon Overlay 3 (GFS Folder)”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\Groove Explorer Icon Overlay 4 (GFS Unread Mark)”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\{72853161-30C5-4D22-B7F9-0BBC1D38A37E}”
Case Else
End Select
‘Win32Assemblies
If RegEnumKey(HKCR,”Installer\Win32Assemblies\”,arrKeys) Then
For Each Item in arrKeys
If InStr(UCase(Item),OREF)>0 Then RegDeleteKey HKCR,”Installer\Win32Assemblies\”&Item
Next ‘Item
End If ‘RegEnumKey
‘Groove blocks reinstall if it locates groove.exe over this key
If RegKeyExists(HKCR,”GrooveFile\Shell\Open\Command\”) Then
sValue = “”
RegReadValue HKCR,”GrooveFile\Shell\Open\Command\”,””,sValue,”REG_SZ”
If InStr(sValue,”\”&OREF&”\”)>0 Then RegDeleteKey HKCR,”GrooveFile”
End If ‘RegKeyExists
End If ‘fRemoveAll
‘Known Keypath settings
For Each key in dicDelRegKey.Keys
If Right(key,1) = “\” Then
RegDeleteKey dicDelRegKey.Item(key),key
Else
iPos = InStrRev(Key,”\”)
If iPos > 0 Then RegDeleteValue dicDelRegKey.Item(key), Left(key,iPos – 1), Mid(key,iPos+1)
End If
Next
‘Add/Remove Programs
RegWipeARP
‘UpgradeCodes, WI config, WI global config
For iLoopCnt = 1 to 5
Select Case iLoopCnt
Case 1
sSubKeyName = “SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes\”
hDefKey = HKLM
Case 2
sSubKeyName = “Installer\UpgradeCodes\”
hDefKey = HKCR
Case 3
sSubKeyName = “SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\”
hDefKey = HKLM
Case 4
sSubKeyName = “Installer\Features\”
hDefKey = HKCR
Case 5
sSubKeyName = “Installer\Products\”
hDefKey = HKCR
Case Else
sSubKeyName = “”
hDefKey = “”
End Select
If RegEnumKey(hDefKey,sSubKeyName,arrKeys) Then
For Each Item in arrKeys
‘Ensure we have the expected length for a compressed GUID
If Len(Item)=32 Then
‘Expand the GUID
sGuid = GetExpandedGuid(Item)
‘Check if it’s an Office key
If Right(sGuid,PRODLEN)=OFFICEID AND Mid(sGuid,4,2) = OVERSIONMAJOR Then
If fRemoveAll Then
RegDeleteKey hDefKey,sSubKeyName & Item
Else
If iLoopCnt delete the value
RegDeleteValue hDefKey, sSubKeyName & Item, Name
End If
Next ‘Name
End If ‘IsArray(arrNames)
‘If all entries were removed – delete the key
RegEnumValues hDefKey,sSubKeyName & Item,arrNames,arrTypes
If Not IsArray(arrNames) Then RegDeleteKey hDefKey, sSubKeyName & Item
Else ‘iLoopCnt >= 3
If CheckDelete(sGuid) Then RegDeleteKey hDefKey, sSubKeyName & Item
End If ‘iLoopCnt 37 Then
If fRemoveAll Then
If (Mid(Item,26,PRODLEN)=OFFICEID AND Mid(Item,4,2)=OVERSIONMAJOR) OR _
LCase(Right(Item,7))=OVERSIONMAJOR&”.data” Then RegDeleteKey HKLM,sSubKeyName & Item
Else
If (Mid(Item,26,PRODLEN)=OFFICEID AND Mid(Item,4,2)=OVERSIONMAJOR) AND _
CheckDelete(UCase(Left(Item,38))) Then RegDeleteKey HKLM,sSubKeyName & Item
End If
End If ’37
Next ‘Item
End If ‘RegEnumKey
‘Registration
hDefKey = HKLM
sSubKeyName = “SOFTWARE\Microsoft\Office\”&OVERSION&”\Registration\”
If RegEnumKey(HKLM,sSubKeyName,arrKeys) Then
For Each Item in arrKeys
If Len(Item)>37 Then
If CheckDelete(UCase(Left(Item,38))) Then RegDeleteKey HKLM,sSubKeyName & Item
End If
Next ‘Item
End If ‘RegEnumKey
‘User Preconfigurations
hDefKey = HKLM
sSubKeyName = “SOFTWARE\Microsoft\Office\”&OVERSION&”\User Settings\”
If RegEnumKey(HKLM,sSubKeyName,arrKeys) Then
For Each Item in arrKeys
If Len(Item)>37 Then
If CheckDelete(UCase(Left(Item,38))) Then RegDeleteKey HKLM,sSubKeyName & Item
End If
Next ‘Item
End If ‘RegEnumKey
‘Click2Run Cleanup
If CInt(OVERSIONMAJOR) > 12 Then RegWipeC2R
‘Temporary entries in ARP
TmpKeyCleanUp
End Sub ‘RegWipeAll
‘=======================================================================================================
‘Clean up Add/Remove Programs registry
Sub RegWipeARP
Dim Item, Name, Sku, key
Dim sSubKeyName, sCurKey, sValue, sGuid
Dim fkeep, fSystemComponent0, fPackages, fDisplayVersion
Dim arrKeys
‘Add/Remove Programs
sSubKeyName = REG_ARP
If RegEnumKey(HKLM,sSubKeyName,arrKeys) Then
For Each Item in arrKeys
‘*0FF1CE*
If Len(Item)>37 Then
sGuid = UCase(Left(Item,38))
If Right(sGuid,PRODLEN)=OFFICEID AND Mid(sGuid,4,2)= OVERSIONMAJOR Then
If CheckDelete(sGuid) Then RegDeleteKey HKLM, sSubKeyName & Item
End If ‘Right(Item,PRODLEN)=OFFICEID
End If ‘Len(Item)>37
‘Config entries
sCurKey = sSubKeyName & Item & “\”
fSystemComponent0 = Not (RegReadValue(HKLM,sCurKey,”SystemComponent”,sValue,”REG_DWORD”) AND (sValue = “1″))
fPackages = RegReadValue(HKLM,sCurKey,OPACKAGE,sValue,”REG_MULTI_SZ”)
fDisplayVersion = RegReadValue(HKLM,sCurKey,”DisplayVersion”,sValue,”REG_SZ”)
If fDisplayVersion AND Len(sValue) > 1 Then
fDisplayVersion = (Left(sValue,2) = OVERSIONMAJOR)
End If
If (fSystemComponent0 AND fPackages AND fDisplayVersion) OR (fSystemComponent0 AND fDisplayVersion AND InStr(UCase(Item),”CLICK2RUN”)>0) Then
fKeep = False
If Not fRemoveAll Then
For Each Sku in dicKeepSku.Keys
If UCase(Item) = OREGREF & Sku Then
fkeep = True
Exit For
End If
Next ‘Sku
End If
If Not fkeep Then RegDeleteKey HKLM, sSubKeyName & Item
End If
Next ‘Item
End If ‘RegEnumKey
End Sub ‘RegWipeARP
‘=======================================================================================================
‘Clean up Click2Run specific registrations
Sub RegWipeC2R
Dim Item
Dim sSubKeyName
Dim arrKeys
‘Click2Run Cleanup
If fRemoveAll OR fRemoveC2R Then
RegDeleteKey HKCU,”Software\Microsoft\Office\CVH”
RegDeleteKey HKCU,”Software\Microsoft\Office\” & OVERSION & “\CVH”
RegDeleteKey HKLM,”Software\Microsoft\Office\” & OVERSION & “\CVH”
RegDeleteKey HKLM,”Software\Microsoft\Office\” & OVERSION & “\CVHSettings”
RegDeleteKey HKLM,”SOFTWARE\Microsoft\Office\” & OVERSION & “\Common\InstallRoot\Virtual”
‘Control Panel Items
RegDeleteKey HKLM,”Software\Microsoft\Windows\CurrentVersion\explorer\ControlPanel\NameSpace\{F9ACD2D6-09C8-4103-995C-912DE68DDE1E}”
RegDeleteKey HKCR,”CLSID\{F9ACD2D6-09C8-4103-995C-912DE68DDE1E}”
RegDeleteKey HKLM,”Software\Microsoft\Windows\CurrentVersion\explorer\ControlPanel\NameSpace\{005CB1F2-224F-4738-B051-91A96758F50C}”
RegDeleteKey HKCR,”CLSID\{005CB1F2-224F-4738-B051-91A96758F50C}”
sSubKeyName = “SOFTWARE\Microsoft\SoftGrid\4.5\Client\Packages\”
If RegEnumKey(HKLM,sSubKeyName,arrKeys) Then
For Each Item in arrKeys
If CheckDelete(Item) Then RegDeleteKey HKLM,sSubKeyName & Item
Next ‘Item
End If ‘RegEnumKey
If RegEnumKey(HKCU,sSubKeyName,arrKeys) Then
For Each Item in arrKeys
If CheckDelete(Item) Then RegDeleteKey HKLM,sSubKeyName & Item
Next ‘Item
End If ‘RegEnumKey
End If
End Sub ‘RegWipeC2R
‘=======================================================================================================
‘Clean up temporary registry keys
Sub TmpKeyCleanUp
Dim TmpKey
If fLogInitialized Then Log ” Remove temporary registry entries”
If IsArray(arrTmpSKUs) Then
For Each TmpKey in arrTmpSKUs
oReg.DeleteKey HKLM, REG_ARP & TmpKey
Next ‘Item
End If ‘IsArray
End Sub ‘TmpKeyCleanUp
‘=======================================================================================================
‘ Helper Functions
‘=======================================================================================================
‘End all running instances of applications that will be removed
Sub CloseOfficeApps
Dim Processes, Process
Dim fWait
Dim iRet
On Error Resume Next
fWait = False
Log ” Doing Action: CloseOfficeApps”
‘OfficeVirt.exe needs to be shut down first
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Process Where Name like ‘officevirt%.exe’”)
For Each Process in Processes
If dicApps.Exists(LCase(Process.Name)) Then
Log ” – End process ” & Process.Name
iRet = Process.Terminate()
CheckError “CloseOfficeApps: ” & “Process.Name”
fWait = True
End If
Next ‘Process
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Process”)
For Each Process in Processes
If dicApps.Exists(LCase(Process.Name)) Then
Log ” – End process ” & Process.Name
iRet = Process.Terminate()
CheckError “CloseOfficeApps: ” & “Process.Name”
If Process.Name = “CVH.EXE” Then fWait = True
End If
Next ‘Process
If fWait Then
wscript.sleep 10000
End If
LogOnly ” End Action: CloseOfficeApps”
End Sub ‘CloseOfficeApps
‘=======================================================================================================
‘CVHBS.exe has no true unattended option
‘To ensure quiet automation does not break this dialog box handler monitors the process
Sub CvhbsDialogHandler
Dim CvhbsQuiet
Dim sRunCmd, sQuote
Set CvhbsQuiet = oFso.CreateTextFile(sScrubDir&”\CvhbsQuiet.vbs”,True,True)
sQuote = “&chr(34)&”
CvhbsQuiet.WriteLine “On Error Resume Next”
CvhbsQuiet.WriteLine “Set oShell = CreateObject(“&chr(34)&”WScript.Shell”&chr(34)&”)”
CvhbsQuiet.WriteLine “Set oWmiLocal = GetObject(“&chr(34)&”winmgmts:\\.\root\cimv2″&chr(34)&”)”
CvhbsQuiet.WriteLine “wscript.sleep 10000″
CvhbsQuiet.WriteLine “Do”
CvhbsQuiet.WriteLine “Set Processes = oWmiLocal.ExecQuery(“&chr(34)&”Select * From Win32_Process Where Name=’cvhbs.exe’”&chr(34)&”)”
CvhbsQuiet.WriteLine “iCnt = Processes.Count”
CvhbsQuiet.WriteLine “If iCnt > 0 Then”
CvhbsQuiet.WriteLine “sCommand = “&chr(34)&”tasklist /FI “&chr(34)&sQuote&chr(34)&”WINDOWTITLE eq click*”&chr(34)&sQuote&chr(34)&” /FO CSV /NH”&chr(34)
CvhbsQuiet.WriteLine “Set oExec = oShell.Exec(sCommand)”
CvhbsQuiet.WriteLine “sCmdOut = oExec.StdOut.ReadAll()”
CvhbsQuiet.WriteLine “Do While oExec.Status = 0″
CvhbsQuiet.WriteLine “WScript.Sleep 200″
CvhbsQuiet.WriteLine “Loop”
CvhbsQuiet.WriteLine “If InStr(sCmdOut,”&chr(34)&”,”&chr(34)&”)>0 Then”
CvhbsQuiet.WriteLine “sCmdOut = Replace(sCmdOut,chr(34),”&chr(34)&chr(34)&”)”
CvhbsQuiet.WriteLine “arrCol = Split(sCmdOut,”&chr(34)&”,”&chr(34)&”)”
CvhbsQuiet.WriteLine “sPid = arrCol(1)”
CvhbsQuiet.WriteLine “oShell.AppActivate sPID”
CvhbsQuiet.WriteLine “oShell.SendKeys “&chr(34)&”{ENTER}”&chr(34)
CvhbsQuiet.WriteLine “End If”
CvhbsQuiet.WriteLine “End If”
CvhbsQuiet.WriteLine “wscript.sleep 10000″
CvhbsQuiet.WriteLine “Loop While iCnt > 0″
CvhbsQuiet.Close
sRunCmd = “cscript “&chr(34)&sScrubDir&”\CvhbsQuiet.vbs”&chr(34)
oWShell.Run sRunCmd, 0, False
End Sub ‘CvhbsDialogHandler
‘=======================================================================================================
‘Ensure Windows Explorer is restarted if needed
Sub RestoreExplorer
Dim Processes
On Error Resume Next
wscript.sleep 1000
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Process Where Name=’explorer.exe’”)
If Processes.Count 1 Then
If Right(sKey,1) = “\” Then sKey = Left(sKey,Len(sKey)-1)
End If
If RegEnumKey(hDefKey,sKey,arrKeys) Then
For Each SubKey in arrKeys
If NOT Len(SubKey) = iValidLength Then
RegDeleteKey hDefKey,sKey & “\” & SubKey
End If
Next ‘SubKey
End If
End Sub ‘EnsureValidWIMetadata
‘=======================================================================================================
‘Create a backup copy of the file in the ScrubDir then delete the file
Sub CopyAndDeleteFile(sFile)
Dim File
On Error Resume Next
If oFso.FileExists(sFile) Then
Set File = oFso.GetFile(sFile)
If Not oFso.FolderExists(sScrubDir & “\” & File.ParentFolder.Name) Then oFso.CreateFolder sScrubDir & “\” & File.ParentFolder.Name
oFso.CopyFile sFile,sScrubDir & “\” & File.ParentFolder.Name & “\” & File.Name,True : CheckError “CopyAndDeleteFile”
Set File = Nothing
DeleteFile(sFile)
End If ‘oFso.FileExists
End Sub ‘CopyAndDeleteFile
‘=======================================================================================================
‘Wrapper to delete a file
Sub DeleteFile(sFile)
Dim File
Dim sFileName, sNewPath
On Error Resume Next
If oFso.FileExists(sFile) Then
LogOnly ” – Delete file: ” & sFile
If Not fDetectOnly Then oFso.DeleteFile sFile,True
If Err 0 Then
CheckError “DeleteFile”
If fForce Then
‘Try to move the file and delete from there
Set File = oFso.GetFile(sFile)
sFileName = File.Name
sNewPath = sScrubDir & “\ScrubTmp”
Set File = Nothing
If Not oFso.FolderExists(sNewPath) Then oFso.CreateFolder(sNewPath)
‘Move the file
LogOnly ” – Move file to: ” & sNewPath & “\” & sFileName
oFso.MoveFile sFile,sNewPath & “\” & sFileName
If Err 0 Then
CheckError “DeleteFile (move)”
End If ‘Err 0
End If ‘fForce
End If ‘Err 0
End If ‘oFso.FileExists
End Sub ‘DeleteFile
‘=======================================================================================================
’64 bit aware wrapper to return the requested folder
Function GetFolderPath(sPath)
GetFolderPath = True
If oFso.FolderExists(sPath) Then Exit Function
If f64 AND oFso.FolderExists(Wow64Folder(sPath)) Then
sPath = Wow64Folder(sPath)
Exit Function
End If
GetFolderPath = False
End Function ‘GetFolderPath
‘=======================================================================================================
‘Enumerates subfolder names of a folder and returns True if subfolders exist
Function EnumFolderNames (sFolder, arrSubFolders)
Dim Folder, Subfolder
Dim sSubFolders
If oFso.FolderExists(sFolder) Then
Set Folder = oFso.GetFolder(sFolder)
For Each Subfolder in Folder.Subfolders
sSubFolders = sSubFolders & Subfolder.Name & “,”
Next ‘Subfolder
End If
If f64 AND oFso.FolderExists(Wow64Folder(sFolder)) Then
Set Folder = oFso.GetFolder(Wow64Folder(sFolder))
For Each Subfolder in Folder.Subfolders
sSubFolders = sSubFolders & Subfolder.Name & “,”
Next ‘Subfolder
End If
If Len(sSubFolders)>0 Then arrSubFolders = RemoveDuplicates(Split(Left(sSubFolders,Len(sSubFolders)-1),”,”))
EnumFolderNames = Len(sSubFolders)>0
End Function ‘EnumFolderNames
‘=======================================================================================================
‘Enumerates subfolders of a folder and returns True if subfolders exist
Function EnumFolders (sFolder, arrSubFolders)
Dim Folder, Subfolder
Dim sSubFolders
If oFso.FolderExists(sFolder) Then
Set Folder = oFso.GetFolder(sFolder)
For Each Subfolder in Folder.Subfolders
sSubFolders = sSubFolders & Subfolder.Path & “,”
Next ‘Subfolder
End If
If f64 AND oFso.FolderExists(Wow64Folder(sFolder)) Then
Set Folder = oFso.GetFolder(Wow64Folder(sFolder))
For Each Subfolder in Folder.Subfolders
sSubFolders = sSubFolders & Subfolder.Path & “,”
Next ‘Subfolder
End If
If Len(sSubFolders)>0 Then arrSubFolders = RemoveDuplicates(Split(Left(sSubFolders,Len(sSubFolders)-1),”,”))
EnumFolders = Len(sSubFolders)>0
End Function ‘EnumFolders
‘=======================================================================================================
Sub GetMseFolderStructure (Folder)
Dim SubFolder
For Each SubFolder in Folder.SubFolders
ReDim Preserve arrMseFolders(UBound(arrMseFolders)+1)
arrMseFolders(UBound(arrMseFolders)) = SubFolder.Path
GetMseFolderStructure SubFolder
Next ‘SubFolder
End Sub ‘GetMseFolderStructure
‘=======================================================================================================
‘Wrapper to delete a folder
Sub DeleteFolder(sFolder)
Dim Folder
Dim sDelFolder, sFolderName, sNewPath
If dicKeepFolder.Exists(LCase(sFolder)) Then Exit Sub
If f64 Then
If dicKeepFolder.Exists(LCase(Wow64Folder(sFolder))) Then Exit Sub
End If
If Len(sFolder) > 1 Then
If Right(sFolder,1) = “\” Then sFolder = Left(sFolder,Len(sFolder)-1)
End If
On Error Resume Next
If oFso.FolderExists(sFolder) Then
sDelFolder = sFolder
ElseIf f64 AND oFso.FolderExists(Wow64Folder(sFolder)) Then
sDelFolder = Wow64Folder(sFolder)
Else
Exit Sub
End If
If Not fDetectOnly Then
LogOnly ” – Delete folder: ” & sDelFolder
oFso.DeleteFolder sDelFolder,True
Else
LogOnly ” – Simulate delete folder: ” & sDelFolder
End If
If Err 0 Then
CheckError “DeleteFolder”
‘Try to move the folder and delete from there
Set Folder = oFso.GetFolder(sDelFolder)
sFolderName = Folder.Name
sNewPath = sScrubDir & “\ScrubTmp”
Set Folder = Nothing
‘Ensure we stay within the same drive
If Not oFso.FolderExists(sNewPath) Then oFso.CreateFolder(sNewPath)
‘Move the folder
LogOnly ” – Moving folder to: ” & sNewPath & “\” & sFolderName
oFso.MoveFolder sFolder,sNewPath & “\” & sFolderName
If Err 0 Then
CheckError “DeleteFolder (move)”
End If ‘Err 0
End If ‘Err 0
End Sub ‘DeleteFolder
‘=======================================================================================================
‘Delete empty folder structures
Sub DeleteEmptyFolders
Dim Folder
Dim sFolder
If Not IsArray(arrDeleteFolders) Then Exit Sub
Log ” Empty Folder Cleanup”
For Each sFolder in arrDeleteFolders
If oFso.FolderExists(sFolder) Then
Set Folder = oFso.GetFolder(sFolder)
If (Folder.Subfolders.Count = 0) AND (Folder.Files.Count = 0) Then
Set Folder = Nothing
SmartDeleteFolder sFolder
End If
End If
Next ‘sFolder
End Sub ‘DeleteEmptyFolders
‘=======================================================================================================
‘Wrapper to delete a folder and remove the empty parent folder structure
Sub SmartDeleteFolder(sFolder)
If oFso.FolderExists(sFolder) Then
If Not fDetectOnly Then
LogOnly “Request SmartDelete for folder: ” & sFolder
SmartDeleteFolderEx sFolder
Else
LogOnly “Simulate request SmartDelete for folder: ” & sFolder
End If
End If
If f64 AND oFso.FolderExists(Wow64Folder(sFolder)) Then
If Not fDetectOnly Then
LogOnly “Request SmartDelete for folder: ” & Wow64Folder(sFolder)
SmartDeleteFolderEx Wow64Folder(sFolder)
Else
LogOnly “Simulate request SmartDelete for folder: ” & Wow64Folder(sFolder)
End If
End If
End Sub ‘SmartDeleteFolder
‘=======================================================================================================
‘Executes the folder delete operation
Sub SmartDeleteFolderEx(sFolder)
Dim Folder
On Error Resume Next
DeleteFolder sFolder : CheckError “SmartDeleteFolderEx”
On Error Goto 0
Set Folder = oFso.GetFolder(oFso.GetParentFolderName(sFolder))
If (Folder.Subfolders.Count = 0) AND (Folder.Files.Count = 0) Then SmartDeleteFolderEx(Folder.Path)
End Sub ‘SmartDeleteFolderEx
‘=======================================================================================================
‘Adds the folder structure to the ‘KeepFolder’ dictionary
Sub AddKeepFolder(sPath)
Dim Folder
If NOT dicKeepFolder.Exists (sPath) Then
dicKeepFolder.Add sPath,sPath
End If
sPath = LCase(oFso.GetParentFolderName(sPath))
If oFso.FolderExists(sPath) Then AddKeepFolder(sPath)
End Sub
‘=======================================================================================================
‘Handles additional folder-path operations on 64 bit environments
Function Wow64Folder(sFolder)
If LCase(Left(sFolder,Len(sWinDir & “\System32″))) = LCase(sWinDir & “\System32″) Then
Wow64Folder = sWinDir & “\syswow64″ & Right(sFolder,Len(sFolder)-Len(sSys32Dir))
ElseIf LCase(Left(sFolder,Len(sProgramFiles))) = LCase(sProgramFiles) Then
Wow64Folder = sProgramFilesX86 & Right(sFolder,Len(sFolder)-Len(sProgramFiles))
Else
Wow64Folder = “?” ‘Return invalid string to ensure the folder cannot exist
End If
End Function ‘Wow64Folder
‘=======================================================================================================
Function HiveString(hDefKey)
On Error Resume Next
Select Case hDefKey
Case HKCR : HiveString = “HKEY_CLASSES_ROOT”
Case HKCU : HiveString = “HKEY_CURRENT_USER”
Case HKLM : HiveString = “HKEY_LOCAL_MACHINE”
Case HKU : HiveString = “HKEY_USERS”
Case Else : HiveString = hDefKey
End Select
End Function
‘=======================================================================================================
Function RegKeyExists(hDefKey,sSubKeyName)
Dim arrKeys
RegKeyExists = False
If oReg.EnumKey(hDefKey,sSubKeyName,arrKeys) = 0 Then RegKeyExists = True
End Function
‘=======================================================================================================
Function RegValExists(hDefKey,sSubKeyName,sName)
Dim arrValueTypes, arrValueNames
Dim i
RegValExists = False
If Not RegKeyExists(hDefKey,sSubKeyName) Then Exit Function
If oReg.EnumValues(hDefKey,sSubKeyName,arrValueNames,arrValueTypes) = 0 AND IsArray(arrValueNames) Then
For i = 0 To UBound(arrValueNames)
If LCase(arrValueNames(i)) = Trim(LCase(sName)) Then RegValExists = True
Next
End If ‘oReg.EnumValues
End Function
‘=======================================================================================================
‘Read the value of a given registry entry
Function RegReadValue(hDefKey, sSubKeyName, sName, sValue, sType)
Dim RetVal
Dim Item
Dim arrValues
Select Case UCase(sType)
Case “1″,”REG_SZ”
RetVal = oReg.GetStringValue(hDefKey,sSubKeyName,sName,sValue)
If Not RetVal = 0 AND f64 Then RetVal = oReg.GetStringValue(hDefKey,Wow64Key(hDefKey, sSubKeyName),sName,sValue)
Case “2″,”REG_EXPAND_SZ”
RetVal = oReg.GetExpandedStringValue(hDefKey,sSubKeyName,sName,sValue)
If Not RetVal = 0 AND f64 Then RetVal = oReg.GetExpandedStringValue(hDefKey,Wow64Key(hDefKey, sSubKeyName),sName,sValue)
Case “7″,”REG_MULTI_SZ”
RetVal = oReg.GetMultiStringValue(hDefKey,sSubKeyName,sName,arrValues)
If Not RetVal = 0 AND f64 Then RetVal = oReg.GetMultiStringValue(hDefKey,Wow64Key(hDefKey, sSubKeyName),sName,arrValues)
If RetVal = 0 Then sValue = Join(arrValues,chr(34))
Case “4″,”REG_DWORD”
RetVal = oReg.GetDWORDValue(hDefKey,sSubKeyName,sName,sValue)
If Not RetVal = 0 AND f64 Then
RetVal = oReg.GetDWORDValue(hDefKey,Wow64Key(hDefKey, sSubKeyName),sName,sValue)
End If
Case “3″,”REG_BINARY”
RetVal = oReg.GetBinaryValue(hDefKey,sSubKeyName,sName,sValue)
If Not RetVal = 0 AND f64 Then RetVal = oReg.GetBinaryValue(hDefKey,Wow64Key(hDefKey, sSubKeyName),sName,sValue)
Case “11″,”REG_QWORD”
RetVal = oReg.GetQWORDValue(hDefKey,sSubKeyName,sName,sValue)
If Not RetVal = 0 AND f64 Then RetVal = oReg.GetQWORDValue(hDefKey,Wow64Key(hDefKey, sSubKeyName),sName,sValue)
Case Else
RetVal = -1
End Select ‘sValue
RegReadValue = (RetVal = 0)
End Function ‘RegReadValue
‘=======================================================================================================
‘Enumerate a registry key to return all values
Function RegEnumValues(hDefKey,sSubKeyName,arrNames, arrTypes)
Dim RetVal, RetVal64
Dim arrNames32, arrNames64, arrTypes32, arrTypes64
If f64 Then
RetVal = oReg.EnumValues(hDefKey,sSubKeyName,arrNames32,arrTypes32)
RetVal64 = oReg.EnumValues(hDefKey,Wow64Key(hDefKey, sSubKeyName),arrNames64,arrTypes64)
If (RetVal = 0) AND (Not RetVal64 = 0) AND IsArray(arrNames32) AND IsArray(arrTypes32) Then
arrNames = arrNames32
arrTypes = arrTypes32
End If
If (Not RetVal = 0) AND (RetVal64 = 0) AND IsArray(arrNames64) AND IsArray(arrTypes64) Then
arrNames = arrNames64
arrTypes = arrTypes64
End If
If (RetVal = 0) AND (RetVal64 = 0) AND IsArray(arrNames32) AND IsArray(arrNames64) AND IsArray(arrTypes32) AND IsArray(arrTypes64) Then
arrNames = RemoveDuplicates(Split((Join(arrNames32,”\”) & “\” & Join(arrNames64,”\”)),”\”))
arrTypes = RemoveDuplicates(Split((Join(arrTypes32,”\”) & “\” & Join(arrTypes64,”\”)),”\”))
End If
Else
RetVal = oReg.EnumValues(hDefKey,sSubKeyName,arrNames,arrTypes)
End If ‘f64
RegEnumValues = ((RetVal = 0) OR (RetVal64 = 0)) AND IsArray(arrNames) AND IsArray(arrTypes)
End Function ‘RegEnumValues
‘=======================================================================================================
‘Enumerate a registry key to return all subkeys
Function RegEnumKey(hDefKey,sSubKeyName,arrKeys)
Dim RetVal, RetVal64
Dim arrKeys32, arrKeys64
If f64 Then
RetVal = oReg.EnumKey(hDefKey,sSubKeyName,arrKeys32)
RetVal64 = oReg.EnumKey(hDefKey,Wow64Key(hDefKey, sSubKeyName),arrKeys64)
If (RetVal = 0) AND (Not RetVal64 = 0) AND IsArray(arrKeys32) Then arrKeys = arrKeys32
If (Not RetVal = 0) AND (RetVal64 = 0) AND IsArray(arrKeys64) Then arrKeys = arrKeys64
If (RetVal = 0) AND (RetVal64 = 0) Then
If IsArray(arrKeys32) AND IsArray (arrKeys64) Then
arrKeys = RemoveDuplicates(Split((Join(arrKeys32,”\”) & “\” & Join(arrKeys64,”\”)),”\”))
ElseIf IsArray(arrKeys64) Then
arrKeys = arrKeys64
Else
arrKeys = arrKeys32
End If
End If
Else
RetVal = oReg.EnumKey(hDefKey,sSubKeyName,arrKeys)
End If ‘f64
RegEnumKey = ((RetVal = 0) OR (RetVal64 = 0)) AND IsArray(arrKeys)
End Function ‘RegEnumKey
‘=======================================================================================================
‘Wrapper around oReg.DeleteValue to handle 64 bit
Sub RegDeleteValue(hDefKey, sSubKeyName, sName)
Dim sWow64Key
Dim iRetVal
If RegValExists(hDefKey,sSubKeyName,sName) Then
On Error Resume Next
If Not fDetectOnly Then
LogOnly ” – Delete registry value: ” & HiveString(hDefKey) & “\” & sSubKeyName & ” -> ” & sName
iRetVal = 0
iRetVal = oReg.DeleteValue(hDefKey, sSubKeyName, sName)
CheckError “RegDeleteValue”
If NOT (iRetVal=0) Then LogOnly ” Delete failed. Return value: “&iRetVal
Else
LogOnly ” – Simulate delete registry value: ” & HiveString(hDefKey) & “\” & sSubKeyName & ” -> ” & sName
End If
On Error Goto 0
End If ‘RegValExists
If f64 Then
sWow64Key = Wow64Key(hDefKey, sSubKeyName)
If RegValExists(hDefKey,sWow64Key,sName) Then
On Error Resume Next
If Not fDetectOnly Then
LogOnly ” – Delete registry value: ” & HiveString(hDefKey) & “\” & sWow64Key & ” -> ” & sName
iRetVal = 0
iRetVal = oReg.DeleteValue(hDefKey, sWow64Key, sName)
CheckError “RegDeleteValue”
If NOT (iRetVal=0) Then LogOnly ” Delete failed. Return value: “&iRetVal
Else
LogOnly ” – Simulate delete registry value: ” & HiveString(hDefKey) & “\” & sWow64Key & ” -> ” & sName
End If
On Error Goto 0
End If ‘RegKeyExists
End If
End Sub ‘RegDeleteValue
‘=======================================================================================================
‘Wrappper around RegDeleteKeyEx to handle 64bit scenrios
Sub RegDeleteKey(hDefKey, sSubKeyName)
Dim sWow64Key
If dicKeepReg.Exists(LCase(sSubKeyName)) Then Exit Sub
If f64 Then
If dicKeepReg.Exists(LCase(Wow64Key(hDefKey, sSubKeyName))) Then Exit Sub
End If
If Len(sSubKeyName) > 1 Then
If Right(sSubKeyName,1) = “\” Then sSubKeyName = Left(sSubKeyName,Len(sSubKeyName)-1)
End If
If RegKeyExists(hDefKey, sSubKeyName) Then
If Not fDetectOnly Then
LogOnly ” – Delete registry key: ” & HiveString(hDefKey) & “\” & sSubKeyName
On Error Resume Next
RegDeleteKeyEx hDefKey, sSubKeyName
On Error Goto 0
Else
LogOnly ” – Simulate delete registry key: ” & HiveString(hDefKey) & “\” & sSubKeyName
End If
End If ‘RegKeyExists
If f64 Then
sWow64Key = Wow64Key(hDefKey, sSubKeyName)
If RegKeyExists(hDefKey,sWow64Key) Then
If Not fDetectOnly Then
LogOnly ” – Delete registry key: ” & HiveString(hDefKey) & “\” & sWow64Key
On Error Resume Next
RegDeleteKeyEx hDefKey, sWow64Key
On Error Goto 0
Else
LogOnly ” – Simulate delete registry key: ” & HiveString(hDefKey) & “\” & sWow64Key
End If
End If ‘RegKeyExists
End If
End Sub ‘RegDeleteKey
‘=======================================================================================================
‘Recursively delete a registry structure
Sub RegDeleteKeyEx(hDefKey, sSubKeyName)
Dim arrSubkeys
Dim sSubkey
Dim iRetVal
On Error Resume Next
oReg.EnumKey hDefKey, sSubKeyName, arrSubkeys
If IsArray(arrSubkeys) Then
For Each sSubkey In arrSubkeys
RegDeleteKeyEx hDefKey, sSubKeyName & “\” & sSubkey
Next
End If
If Not fDetectOnly Then
iRetVal = 0
iRetVal = oReg.DeleteKey(hDefKey,sSubKeyName)
If NOT (iRetVal=0) Then LogOnly ” Delete failed. Return value: “&iRetVal
End If
End Sub ‘RegDeleteKeyEx
‘=======================================================================================================
‘Return the alternate regkey location on 64bit environment
Function Wow64Key(hDefKey, sSubKeyName)
Dim iPos
Select Case hDefKey
Case HKCU
If Left(sSubKeyName,17) = “Software\Classes\” Then
Wow64Key = Left(sSubKeyName,17) & “Wow6432Node\” & Right(sSubKeyName,Len(sSubKeyName)-17)
Else
iPos = InStr(sSubKeyName,”\”)
Wow64Key = Left(sSubKeyName,iPos) & “Wow6432Node\” & Right(sSubKeyName,Len(sSubKeyName)-iPos)
End If
Case HKLM
If Left(sSubKeyName,17) = “Software\Classes\” Then
Wow64Key = Left(sSubKeyName,17) & “Wow6432Node\” & Right(sSubKeyName,Len(sSubKeyName)-17)
Else
iPos = InStr(sSubKeyName,”\”)
Wow64Key = Left(sSubKeyName,iPos) & “Wow6432Node\” & Right(sSubKeyName,Len(sSubKeyName)-iPos)
End If
Case Else
Wow64Key = “Wow6432Node\” & sSubKeyName
End Select ‘hDefKey
End Function ‘Wow64Key
‘=======================================================================================================
‘Remove duplicate entries from a one dimensional array
Function RemoveDuplicates(Array)
Dim Item
Dim oDic
Set oDic = CreateObject(“Scripting.Dictionary”)
For Each Item in Array
If Not oDic.Exists(Item) Then oDic.Add Item,Item
Next ‘Item
RemoveDuplicates = oDic.Keys
End Function ‘RemoveDuplicates
‘=======================================================================================================
‘Uses WMI to stop a service
Function StopService(sService)
Dim Services, Service
Dim sQuery
Dim iRet
On Error Resume Next
iRet = 0
sQuery = “Select * From Win32_Service Where Name=’” & sService & “‘”
Set Services = oWmiLocal.Execquery(sQuery)
‘Stop the service
For Each Service in Services
If UCase(Service.State) = “STARTED” Then iRet = Service.StopService
If UCase(Service.State) = “RUNNING” Then iRet = Service.StopService
Next ‘Service
StopService = (iRet = 0)
End Function ‘StopService
‘=======================================================================================================
‘Delete a service
Sub DeleteService(sService)
Dim Services, Service, Processes, Process
Dim sQuery, sStates
Dim iRet
On Error Resume Next
sStates = “STARTED;RUNNING”
sQuery = “Select * From Win32_Service Where Name=’” & sService & “‘”
Set Services = oWmiLocal.Execquery(sQuery)
‘Stop and delete the service
For Each Service in Services
Log ” Found service ” & sService & ” in state ” & Service.State
If InStr(sStates,UCase(Service.State))>0 Then iRet = Service.StopService()
‘Ensure no more instances of the service are running
Set Processes = oWmiLocal.ExecQuery(“Select * From Win32_Process Where Name=’” & sService & “.exe’”)
For Each Process in Processes
iRet = Process.Terminate()
Next ‘Process
If Not fDetectOnly Then
Log ” – Deleting Service -> ” & sService
iRet = Service.Delete()
Else
Log ” – Simulate deleting Service -> ” & sService
End If
Next ‘Service
Set Services = Nothing
Err.Clear
End Sub ‘DeleteService
‘=======================================================================================================
‘Translation for setup.exe error codes
Function SetupExeRetVal(RetVal)
Select Case RetVal
Case 0 : SetupExeRetVal = “Success”
Case 30001,1 : SetupExeRetVal = “AbstractMethod”
Case 30002,2 : SetupExeRetVal = “ApiProhibited”
Case 30003,3 : SetupExeRetVal = “AlreadyImpersonatingAUser”
Case 30004,4 : SetupExeRetVal = “AlreadyInitialized”
Case 30005,5 : SetupExeRetVal = “ArgumentNullException”
Case 30006,6 : SetupExeRetVal = “AssertionFailed”
Case 30007,7 : SetupExeRetVal = “CABFileAddFailed”
Case 30008,8 : SetupExeRetVal = “CommandFailed”
Case 30009,9 : SetupExeRetVal = “ConcatenationFailed”
Case 30010,10 : SetupExeRetVal = “CopyFailed”
Case 30011,11 : SetupExeRetVal = “CreateEventFailed”
Case 30012,12 : SetupExeRetVal = “CustomizationPatchNotFound”
Case 30013,13 : SetupExeRetVal = “CustomizationPatchNotApplicable”
Case 30014,14 : SetupExeRetVal = “DuplicateDefinition”
Case 30015,15 : SetupExeRetVal = “ErrorCodeOnly – Passthrough for Win32 error”
Case 30016,16 : SetupExeRetVal = “ExceptionNotThrown”
Case 30017,17 : SetupExeRetVal = “FailedToImpersonateUser”
Case 30018,18 : SetupExeRetVal = “FailedToInitializeFlexDataSource”
Case 30019,19 : SetupExeRetVal = “FailedToStartClassFactories”
Case 30020,20 : SetupExeRetVal = “FileNotFound”
Case 30021,21 : SetupExeRetVal = “FileNotOpen”
Case 30022,22 : SetupExeRetVal = “FlexDialogAlreadyInitialized”
Case 30023,23 : SetupExeRetVal = “HResultOnly – Passthrough for HRESULT errors”
Case 30024,24 : SetupExeRetVal = “HWNDNotFound”
Case 30025,25 : SetupExeRetVal = “IncompatibleCacheAction”
Case 30026,26 : SetupExeRetVal = “IncompleteProductAddOns”
Case 30027,27 : SetupExeRetVal = “InstalledProductStateCorrupt”
Case 30028,28 : SetupExeRetVal = “InsufficientBuffer”
Case 30029,29 : SetupExeRetVal = “InvalidArgument”
Case 30030,30 : SetupExeRetVal = “InvalidCDKey”
Case 30031,31 : SetupExeRetVal = “InvalidColumnType”
Case 30032,31 : SetupExeRetVal = “InvalidConfigAddLanguage”
Case 30033,33 : SetupExeRetVal = “InvalidData”
Case 30034,34 : SetupExeRetVal = “InvalidDirectory”
Case 30035,35 : SetupExeRetVal = “InvalidFormat”
Case 30036,36 : SetupExeRetVal = “InvalidInitialization”
Case 30037,37 : SetupExeRetVal = “InvalidMethod”
Case 30038,38 : SetupExeRetVal = “InvalidOperation”
Case 30039,39 : SetupExeRetVal = “InvalidParameter”
Case 30040,40 : SetupExeRetVal = “InvalidProductFromARP”
Case 30041,41 : SetupExeRetVal = “InvalidProductInConfigXml”
Case 30042,42 : SetupExeRetVal = “InvalidReference”
Case 30043,43 : SetupExeRetVal = “InvalidRegistryValueType”
Case 30044,44 : SetupExeRetVal = “InvalidXMLProperty”
Case 30045,45 : SetupExeRetVal = “InvalidMetadataFile”
Case 30046,46 : SetupExeRetVal = “LogNotInitialized”
Case 30047,47 : SetupExeRetVal = “LogAlreadyInitialized”
Case 30048,48 : SetupExeRetVal = “MissingXMLNode”
Case 30049,49 : SetupExeRetVal = “MsiTableNotFound”
Case 30050,50 : SetupExeRetVal = “MsiAPICallFailure”
Case 30051,51 : SetupExeRetVal = “NodeNotOfTypeElement”
Case 30052,52 : SetupExeRetVal = “NoMoreGraceBoots”
Case 30053,53 : SetupExeRetVal = “NoProductsFound”
Case 30054,54 : SetupExeRetVal = “NoSupportedCulture”
Case 30055,55 : SetupExeRetVal = “NotYetImplemented”
Case 30056,56 : SetupExeRetVal = “NotAvailableCulture”
Case 30057,57 : SetupExeRetVal = “NotCustomizationPatch”
Case 30058,58 : SetupExeRetVal = “NullReference”
Case 30059,59 : SetupExeRetVal = “OCTPatchForbidden”
Case 30060,60 : SetupExeRetVal = “OCTWrongMSIDll”
Case 30061,61 : SetupExeRetVal = “OutOfBoundsIndex”
Case 30062,62 : SetupExeRetVal = “OutOfDiskSpace”
Case 30063,63 : SetupExeRetVal = “OutOfMemory”
Case 30064,64 : SetupExeRetVal = “OutOfRange”
Case 30065,65 : SetupExeRetVal = “PatchApplicationFailure”
Case 30066,66 : SetupExeRetVal = “PreReqCheckFailure”
Case 30067,67 : SetupExeRetVal = “ProcessAlreadyStarted”
Case 30068,68 : SetupExeRetVal = “ProcessNotStarted”
Case 30069,69 : SetupExeRetVal = “ProcessNotFinished”
Case 30070,70 : SetupExeRetVal = “ProductAlreadyDefined”
Case 30071,71 : SetupExeRetVal = “ResourceAlreadyTracked”
Case 30072,72 : SetupExeRetVal = “ResourceNotFound”
Case 30073,73 : SetupExeRetVal = “ResourceNotTracked”
Case 30074,74 : SetupExeRetVal = “SQLAlreadyConnected”
Case 30075,75 : SetupExeRetVal = “SQLFailedToAllocateHandle”
Case 30076,76 : SetupExeRetVal = “SQLFailedToConnect”
Case 30077,77 : SetupExeRetVal = “SQLFailedToExecuteStatement”
Case 30078,78 : SetupExeRetVal = “SQLFailedToRetrieveData”
Case 30079,79 : SetupExeRetVal = “SQLFailedToSetAttribute”
Case 30080,80 : SetupExeRetVal = “StorageNotCreated”
Case 30081,81 : SetupExeRetVal = “StreamNameTooLong”
Case 30082,82 : SetupExeRetVal = “SystemError”
Case 30083,83 : SetupExeRetVal = “ThreadAlreadyStarted”
Case 30084,84 : SetupExeRetVal = “ThreadNotStarted”
Case 30085,85 : SetupExeRetVal = “ThreadNotFinished”
Case 30086,86 : SetupExeRetVal = “TooManyProducts”
Case 30087,87 : SetupExeRetVal = “UnexpectedXMLNodeType”
Case 30088,88 : SetupExeRetVal = “UnexpectedError”
Case 30089,89 : SetupExeRetVal = “Unitialized”
Case 30090,90 : SetupExeRetVal = “UserCancel”
Case 30091,91 : SetupExeRetVal = “ExternalCommandFailed”
Case 30092,92 : SetupExeRetVal = “SPDatabaseOverSize”
Case 30093,93 : SetupExeRetVal = “IntegerTruncation”
‘msiexec return values
Case 1259 : SetupExeRetVal = “APPHELP_BLOCK”
Case 1601 : SetupExeRetVal = “INSTALL_SERVICE_FAILURE”
Case 1602 : SetupExeRetVal = “INSTALL_USEREXIT”
Case 1603 : SetupExeRetVal = “INSTALL_FAILURE”
Case 1604 : SetupExeRetVal = “INSTALL_SUSPEND”
Case 1605 : SetupExeRetVal = “UNKNOWN_PRODUCT”
Case 1606 : SetupExeRetVal = “UNKNOWN_FEATURE”
Case 1607 : SetupExeRetVal = “UNKNOWN_COMPONENT”
Case 1608 : SetupExeRetVal = “UNKNOWN_PROPERTY”
Case 1609 : SetupExeRetVal = “INVALID_HANDLE_STATE”
Case 1610 : SetupExeRetVal = “BAD_CONFIGURATION”
Case 1611 : SetupExeRetVal = “INDEX_ABSENT”
Case 1612 : SetupExeRetVal = “INSTALL_SOURCE_ABSENT”
Case 1613 : SetupExeRetVal = “INSTALL_PACKAGE_VERSION”
Case 1614 : SetupExeRetVal = “PRODUCT_UNINSTALLED”
Case 1615 : SetupExeRetVal = “BAD_QUERY_SYNTAX”
Case 1616 : SetupExeRetVal = “INVALID_FIELD”
Case 1618 : SetupExeRetVal = “INSTALL_ALREADY_RUNNING”
Case 1619 : SetupExeRetVal = “INSTALL_PACKAGE_OPEN_FAILED”
Case 1620 : SetupExeRetVal = “INSTALL_PACKAGE_INVALID”
Case 1621 : SetupExeRetVal = “INSTALL_UI_FAILURE”
Case 1622 : SetupExeRetVal = “INSTALL_LOG_FAILURE”
Case 1623 : SetupExeRetVal = “INSTALL_LANGUAGE_UNSUPPORTED”
Case 1624 : SetupExeRetVal = “INSTALL_TRANSFORM_FAILURE”
Case 1625 : SetupExeRetVal = “INSTALL_PACKAGE_REJECTED”
Case 1626 : SetupExeRetVal = “FUNCTION_NOT_CALLED”
Case 1627 : SetupExeRetVal = “FUNCTION_FAILED”
Case 1628 : SetupExeRetVal = “INVALID_TABLE”
Case 1629 : SetupExeRetVal = “DATATYPE_MISMATCH”
Case 1630 : SetupExeRetVal = “UNSUPPORTED_TYPE”
Case 1631 : SetupExeRetVal = “CREATE_FAILED”
Case 1632 : SetupExeRetVal = “INSTALL_TEMP_UNWRITABLE”
Case 1633 : SetupExeRetVal = “INSTALL_PLATFORM_UNSUPPORTED”
Case 1634 : SetupExeRetVal = “INSTALL_NOTUSED”
Case 1635 : SetupExeRetVal = “PATCH_PACKAGE_OPEN_FAILED”
Case 1636 : SetupExeRetVal = “PATCH_PACKAGE_INVALID”
Case 1637 : SetupExeRetVal = “PATCH_PACKAGE_UNSUPPORTED”
Case 1638 : SetupExeRetVal = “PRODUCT_VERSION”
Case 1639 : SetupExeRetVal = “INVALID_COMMAND_LINE”
Case 1640 : SetupExeRetVal = “INSTALL_REMOTE_DISALLOWED”
Case 1641 : SetupExeRetVal = “SUCCESS_REBOOT_INITIATED”
Case 1642 : SetupExeRetVal = “PATCH_TARGET_NOT_FOUND”
Case 1643 : SetupExeRetVal = “PATCH_PACKAGE_REJECTED”
Case 1644 : SetupExeRetVal = “INSTALL_TRANSFORM_REJECTED”
Case 1645 : SetupExeRetVal = “INSTALL_REMOTE_PROHIBITED”
Case 1646 : SetupExeRetVal = “PATCH_REMOVAL_UNSUPPORTED”
Case 1647 : SetupExeRetVal = “UNKNOWN_PATCH”
Case 1648 : SetupExeRetVal = “PATCH_NO_SEQUENCE”
Case 1649 : SetupExeRetVal = “PATCH_REMOVAL_DISALLOWED”
Case 1650 : SetupExeRetVal = “INVALID_PATCH_XML”
Case 3010 : SetupExeRetVal = “SUCCESS_REBOOT_REQUIRED”
Case Else : SetupExeRetVal = “Unknown Return Value”
End Select
End Function ‘SetupExeRetVal
‘=======================================================================================================
Function GetProductID(sProdID)
Dim sReturn
Select Case sProdId
Case “0010″ : sReturn = “WEBFLDRS”
Case “0011″ : sReturn = “PROPLUS”
Case “0012″ : sReturn = “STANDARD”
Case “0013″ : sReturn = “BASIC”
Case “0014″ : sReturn = “PRO”
Case “0015″ : sReturn = “ACCESS”
Case “0016″ : sReturn = “EXCEL”
Case “0017″ : sReturn = “SharePointDesigner”
Case “0018″ : sReturn = “PowerPoint”
Case “0019″ : sReturn = “Publisher”
Case “001A” : sReturn = “Outlook”
Case “001B” : sReturn = “Word”
Case “001C” : sReturn = “AccessRuntime”
Case “001F” : sReturn = “Proof”
Case “0020″ : sReturn = “O2007CNV”
Case “0021″ : sReturn = “VisualWebDeveloper”
Case “0026″ : sReturn = “ExpressionWeb”
Case “0029″ : sReturn = “Excel”
Case “002A” : sReturn = “Office64″
Case “002B” : sReturn = “Word”
Case “002C” : sReturn = “Proofing”
Case “002E” : sReturn = “Ultimate”
Case “002F” : sReturn = “HomeAndStudent”
Case “0028″ : sReturn = “IME”
Case “0030″ : sReturn = “Enterprise”
Case “0031″ : sReturn = “ProfessionalHybrid”
Case “0033″ : sReturn = “Personal”
Case “0035″ : sReturn = “ProfessionalHybrid”
Case “0037″ : sReturn = “PowerPoint”
Case “0038″ : sReturn = “OlTimeZoneTool”
Case “003A” : sReturn = “PrjStd”
Case “003B” : sReturn = “PrjPro”
Case “0043″ : sReturn = “OlTimeZoneEngine”
Case “0044″ : sReturn = “InfoPath”
Case “0045″ : sReturn = “XWEB”
Case “004A” : sReturn = “OWC11″
Case “0051″ : sReturn = “VISPRO”
Case “0052″ : sReturn = “VisView”
Case “0053″ : sReturn = “VisStd”
Case “0054″ : sReturn = “VisMUI”
Case “0055″ : sReturn = “VisMUI”
Case “006E” : sReturn = “Shared”
Case “008A” : sReturn = “RecentDocs”
Case “00A1″ : sReturn = “ONENOTE”
Case “00A3″ : sReturn = “OneNoteHomeStudent”
Case “00A4″ : sReturn = “OWC11″
Case “00A7″ : sReturn = “CPAO”
Case “00A9″ : sReturn = “InterConnect”
Case “00AF” : sReturn = “PPtView”
Case “00B0″ : sReturn = “ExPdf”
Case “00B1″ : sReturn = “ExXps”
Case “00B2″ : sReturn = “ExPdfXps”
Case “00B4″ : sReturn = “PrjMUI”
Case “00B5″ : sReturn = “PrjtMUI”
Case “00B9″ : sReturn = “AER”
Case “00BA” : sReturn = “Groove”
Case “00CA” : sReturn = “SmallBusiness”
Case “00E0″ : sReturn = “Outlook”
Case “00D1″ : sReturn = “ACE”
Case “0100″ : sReturn = “OfficeMUI”
Case “0101″ : sReturn = “OfficeXMUI”
Case “0103″ : sReturn = “PTK”
Case “0114″ : sReturn = “GrooveSetupMetadata”
Case “0115″ : sReturn = “SharedSetupMetadata”
Case “0116″ : sReturn = “SharedSetupMetadata”
Case “0117″ : sReturn = “AccessSetupMetadata”
Case “011A” : sReturn = “LWConnect”
Case “011F” : sReturn = “OLConnect”
Case “1014″ : sReturn = “STS”
Case “1015″ : sReturn = “WSSMUI”
Case “1032″ : sReturn = “PJSVRAPP”
Case “104B” : sReturn = “SPS”
Case “104E” : sReturn = “SPSMUI”
Case “107F” : sReturn = “OSrv”
Case “1080″ : sReturn = “OSrv”
Case “1088″ : sReturn = “lpsrvwfe”
Case “10D7″ : sReturn = “IFS”
Case “10D8″ : sReturn = “IFSMUI”
Case “10EB” : sReturn = “DLCAPP”
Case “10F5″ : sReturn = “XLSRVAPP”
Case “10F6″ : sReturn = “XlSrvWFE”
Case “10F7″ : sReturn = “DLC”
Case “10F8″ : sReturn = “SlSrvMui”
Case “10FB” : sReturn = “OSrchWFE”
Case “10FC” : sReturn = “OSRCHAPP”
Case “10FD” : sReturn = “OSrchMUI”
Case “1103″ : sReturn = “DLC”
Case “1104″ : sReturn = “LHPSRV”
Case “1105″ : sReturn = “PIA”
Case “110D” : sReturn = “OSERVER”
Case “110F” : sReturn = “PSERVER”
Case “1110″ : sReturn = “WSS”
Case “1121″ : sReturn = “SPSSDK”
Case “1122″ : sReturn = “SPSDev”
Case Else : sReturn = “”
End Select ‘sProdId
GetProductID = sReturn
End Function ‘GetProductID
‘=======================================================================================================
Sub Log (sLog)
wscript.echo sLog
LogStream.WriteLine sLog
End Sub ‘Log
‘=======================================================================================================
Sub LogOnly (sLog)
LogStream.WriteLine sLog
End Sub ‘Log
‘=======================================================================================================
Sub CheckError(sModule)
If Err 0 Then
LogOnly ” ” & Now & ” – ” & sModule & ” – Source: ” & Err.Source & “; Err# (Hex): ” & Hex( Err ) & _
“; Err# (Dec): ” & Err & “; Description : ” & Err.Description
End If ‘Err = 0
Err.Clear
End Sub
‘=======================================================================================================
‘Command line parser
Sub ParseCmdLine
Dim iCnt, iArgCnt
Dim arrArguments
Dim sArg0
iArgCnt = Wscript.Arguments.Count
If iArgCnt = 0 Then
Select Case UCase(wscript.ScriptName)
Case UCase(SCRIPTNAME)&”_WAC.VBS”
ReDim arrArguments(0)
Case Else
‘Create the log
CreateLog
Log “No argument specified. Preparing user prompt” & vbCrLf
FindInstalledOProducts
If dicInstalledSku.Count > 0 Then sDefault = Join(RemoveDuplicates(dicInstalledSku.Items),”,”) Else sDefault = “CLIENTALL”
sDefault = InputBox(“Enter a list of ” & ONAME & ” products to remove” & vbCrLf & vbCrLf & _
“Examples:” & vbCrLf & _
“CLIENTALL” & vbTab & “-> all Client products” & vbCrLf & _
“SERVER” & vbTab & “-> all Server products” & vbCrLf & _
“ALL” & vbTab & vbTab & “-> all Server & Client products” & vbCrLf & _
“ProPlus,PrjPro” & vbTab & “-> ProPlus and Project” & vbCrLf &_
“?” & vbTab & vbTab & “-> display Help”, _
SCRIPTFILE & ” – ” & ONAME & ” remover”, _
sDefault)
If IsEmpty(sDefault) Then ‘User cancelled
Log “User cancelled. CleanUp & Exit.”
‘Undo temporary entries created in ARP
TmpKeyCleanUp
wscript.quit 1602
End If ‘IsEmpty(sDefault)
Log “Answer from prompt: ” & sDefault & vbCrLf
sDefault = Trim(UCase(Trim(Replace(sDefault,Chr(34),””))))
arrArguments = Split(Trim(sDefault),” “)
If UBound(arrArguments) = -1 Then ReDim arrArguments(0)
End Select
Else
ReDim arrArguments(iArgCnt-1)
For iCnt = 0 To (iArgCnt-1)
arrArguments(iCnt) = UCase(Wscript.Arguments(iCnt))
Next ‘iCnt
End If ‘iArgCnt = 0
‘Handle the SKU list
Select Case UCase(wscript.ScriptName)
Case UCase(SCRIPTNAME)&”_WAC.VBS”
sArg0 = “WCSERVER”
Case Else
sArg0 = Replace(arrArguments(0),”/”,””)
sArg0 = Replace(sArg0,”-”,””)
End Select
Select Case UCase(sArg0)
Case “?”
ShowSyntax
Case “ALL”
fRemoveAll = True
fRemoveOse = False
Case “CLIENTSUITES”
fRemoveCSuites = True
fRemoveOse = False
Case “CLIENTSTANDALONE”
fRemoveCSingle = True
fRemoveOse = False
Case “CLIENTALL”
fRemoveCSuites = True
fRemoveCSingle = True
fRemoveOse = False
Case “SERVER”
fRemoveServer = True
fRemoveOse = False
Case “ALL,OSE”
fRemoveAll = True
fRemoveOse = True
Case Else
fRemoveAll = False
fRemoveOse = False
sSkuRemoveList = sArg0
End Select
For iCnt = 0 To UBound(arrArguments)
Select Case arrArguments(iCnt)
Case “?”,”/?”,”-?”
ShowSyntax
Case “/B”,”/BYPASS”
If UBound(arrArguments)>iCnt Then
If InStr(arrArguments(iCnt+1),”1″)>0 Then fBypass_Stage1 = True
If InStr(arrArguments(iCnt+1),”2″)>0 Then fBypass_Stage2 = True
If InStr(arrArguments(iCnt+1),”3″)>0 Then fBypass_Stage3 = True
If InStr(arrArguments(iCnt+1),”4″)>0 Then fBypass_Stage4 = True
End If
Case “/D”,”/DELETEUSERSETTINGS”
fKeepUser = False
Case “/FR”,”/FASTREMOVE”
fBypass_Stage1 = True
fSkipSD = True
Case “/F”,”/FORCE”
fForce = True
Case “/K”,”/KEEPUSERSETTINGS”
fKeepUser = True
Case “/L”,”/LOG”
fLogInitialized = False
If UBound(arrArguments)>iCnt Then
If oFso.FolderExists(arrArguments(iCnt+1)) Then
sLogDir = arrArguments(iCnt+1)
Else
On Error Resume Next
oFso.CreateFolder(arrArguments(iCnt+1))
If Err 0 Then sLogDir = sScrubDir Else sLogDir = arrArguments(iCnt+1)
End If
End If
Case “/N”,”/NOCANCEL”
fNoCancel = True
Case “/O”,”/OSE”
fRemoveOse = True
Case “/P”,”/PREVIEW”,”/DETECTONLY”
fDetectOnly = True
Case “/Q”,”/QUIET”
fQuiet = True
Case “/QND”
fBypass_Stage1 = True
fBypass_Stage2 = True
fBypass_Stage3 = True
fRemoveOse = True
fRemoveOspp = True
fRemoveC2R = True
fRemoveAll = True
fSkipSD = True
fForce = True
Case “/S”,”/SKIPSD”,”/SKIPSHORTCUSTDETECTION”
fSkipSD = True
Case Else
End Select
Next ‘iCnt
If Not fLogInitialized Then CreateLog
End Sub ‘ParseCmdLine
‘=======================================================================================================
Sub CreateLog
Dim DateTime
Dim sLogName
On Error Resume Next
‘Create the log file
Set DateTime = CreateObject(“WbemScripting.SWbemDateTime”)
DateTime.SetVarDate Now,True
sLogName = sLogDir & “\” & oWShell.ExpandEnvironmentStrings(“%COMPUTERNAME%”)
sLogName = sLogName & “_” & Left(DateTime.Value,14)
sLogName = sLogName & “_ScrubLog.txt”
Err.Clear
Set LogStream = oFso.CreateTextFile(sLogName,True,True)
If Err 0 Then
Err.Clear
sLogDir = sScrubDir
sLogName = sLogDir & “\” & oWShell.ExpandEnvironmentStrings(“%COMPUTERNAME%”)
sLogName = sLogName & “_” & Left(DateTime.Value,14)
sLogName = sLogName & “_ScrubLog.txt”
Set LogStream = oFso.CreateTextFile(sLogName,True,True)
End If
Log “Microsoft Customer Support Services – ” & ONAME & ” Removal Utility” & vbCrLf & vbCrLf & _
“Version: ” & SCRIPTVERSION & vbCrLf & _
“64 bit OS: ” & f64 & vbCrLf & _
“Start removal: ” & Now & vbCrLf
fLogInitialized = True
End Sub ‘CreateLog
‘=======================================================================================================
Sub RelaunchAsCScript
Dim Argument
Dim sCmdLine
sCmdLine = “cmd.exe /k ” & WScript.Path & “\cscript.exe //NOLOGO ” & Chr(34) & WScript.scriptFullName & Chr(34)
If Wscript.Arguments.Count > 0 Then
For Each Argument in Wscript.Arguments
sCmdLine = sCmdLine & ” ” & chr(34) & Argument & chr(34)
Next ‘Argument
End If
oWShell.Run sCmdLine,1,False
Wscript.Quit
End Sub ‘RelaunchAsCScript
‘=======================================================================================================
Sub RelaunchElevated
Dim Argument
Dim sCmdLine
Dim oShell
Set oShell = CreateObject(“Shell.Application”)
sCmdLine = Chr(34) & WScript.scriptFullName & Chr(34)
If Wscript.Arguments.Count > 0 Then
For Each Argument in Wscript.Arguments
If Argument = “UAC” Then Exit Sub
sCmdLine = sCmdLine & ” ” & chr(34) & Argument & chr(34)
Next ‘Argument
End If
oShell.ShellExecute “cscript.exe”, sCmdLine & ” UAC”, “”, “runas”, 1
Wscript.Quit
End Sub ‘RelaunchAsCScript
‘=======================================================================================================
‘Show the expected syntax for the script usage
Sub ShowSyntax
TmpKeyCleanUp
Wscript.Echo sErr & vbCrLf & _
SCRIPTFILE & ” V ” & SCRIPTVERSION & vbCrLf & _
“Copyright (c) Microsoft Corporation. All Rights Reserved” & vbCrLf & vbCrLf & _
SCRIPTFILE & ” helps to remove ” & ONAME & ” Server & Client products” & vbCrLf & _
“when a regular uninstall is no longer possible” & vbCrLf & vbCrLf & _
“Usage:” & vbTab & SCRIPTFILE & ” [List of config ProductIDs] [Options]” & vbCrLf & vbCrLf & _
vbTab & “/? ‘ Displays this help”& vbCrLf &_
vbTab & “/Force ‘ Enforces file removal. May cause data loss!” & vbCrLf &_
vbTab & “/SkipShortcutDetection ‘ Does not search the local hard drives for shortcuts” & vbCrLf & _
vbTab & “/Log [LogfolderPath] ‘ Custom folder for log files” & vbCrLf & _
vbTab & “/NoCancel ‘ Setup.exe and Msiexec.exe have no Cancel button” & vbCrLf &_
vbTab & “/OSE ‘ Forces removal of the Office Source Engine service” & vbCrLf &_
vbTab & “/Quiet ‘ Setup.exe and Msiexec.exe run quiet with no UI” & vbCrLf &_
vbTab & “/Preview ‘ Run this script to preview what would get removed”& vbCrLf & vbCrLf & _
“Examples:”& vbCrLf & _
vbTab & SCRIPTFILE & ” CLIENTALL ‘ Remove all ” & ONAME & ” Client products” & vbCrLf &_
vbTab & SCRIPTFILE & ” SERVER ‘ Remove all ” & ONAME & ” Server products” & vbCrLf &_
vbTab & SCRIPTFILE & ” ALL ‘ Remove all ” & ONAME & ” Server & Client products” & vbCrLf &_
vbTab & SCRIPTFILE & ” ProPlus,PrjPro ‘ Remove ProPlus and Project” & vbCrLf
Wscript.Quit
End Sub ‘ShowSyntax
‘=======================================================================================================
************************************************************************
DCM Admin.VBS
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
wscript.quit
*******************************************
*********SMS/SCCM Command-line Actions***********
WMIC is a very powerful but rarely used tool to manage WMI from Command-line and it’s part of the Operating-system since WindowsXP…. !
Some examples to trigger SMS/SCCM Client Actions from command line:
Disable Software-Distribution:
WMIC /namespace:\\root\ccm\policy\machine\requestedconfig path ccm_SoftwareDistributionClientConfig CREATE ComponentName=”Disable SWDist”,Enabled=”false”,LockSettings=”TRUE”,PolicySource=”local”,PolicyVersion=”1.0″ ,SiteSettingsKey=”1″ /NOINTERACTIVE
Re-Activate Software-Distribution:
WMIC /namespace:\\root\ccm\policy\machine\requestedconfig path ccm_SoftwareDistributionClientConfig WHERE ComponentName=”Disable SWDist” delete /NOINTERACTIVE
Trigger Hardware Inventory:
WMIC /namespace:\\root\ccm path sms_client CALL TriggerSchedule “{00000000-0000-0000-0000-000000000001}” /NOINTERACTIVE
Trigger Software Inventory:
WMIC /namespace:\\root\ccm path sms_client CALL TriggerSchedule “{00000000-0000-0000-0000-000000000002}” /NOINTERACTIVE
Trigger DataDiscoverRecord (DDR) update:
WMIC /namespace:\\root\ccm path sms_client CALL TriggerSchedule “{00000000-0000-0000-0000-000000000003}” /NOINTERACTIVE
Force a FULL HW Inventory on next HW-Inv Schedule:
WMIC /namespace:\\root\ccm\invagt path inventoryActionStatus where InventoryActionID=”{00000000-0000-0000-0000-000000000001}” DELETE /NOINTERACTIVE
Repair SMS/SCCM Agent on a remote client:
WMIC /node:%MACHINE% /namespace:\\root\ccm path sms_client CALL RepairClient
Repair a list (all clients listed in clients.txt) of remote SMS/SCCM Agents:
WMIC /node:@clients.txt /namespace:\\root\ccm path sms_client CALL RepairClient
*******************************
http://wmug.co.uk/blogs/eskonr/archive/2010/11.aspx
*************************************************
***********SCCM : Copy and Paste, context menu add-on***********
******************************************************************
Updates*******
sc config wuauserv start= Auto
sc start wuauserv
************************
BITS
sc config BITS start= Auto
sc start BITS
***********
PSTOOLS
Assume Installed on C Drive..Folder name is PStools
Psexec.exe \\hostname(IPaddress) -c -u Domain\username -p PASSWORD ABD.bat
SCCM Client Issues Fix batch file
http://sccm.blog.com/2012/07/03/sccm-client-issues-fix-batch-file/
***************
Install.bat
\\10.10.10.10\e$\Softwares\Client\ccmsetup.exe /source:\\10.10.10.10\e$\Softwares\Client /mp:KML-PSS-01.ABCD.co.in SMSSLP=KML-PSS-01.ABCD.co.in SMSSITECODE=KML FSP=KML-PSS-01.abcd.co.in
*************************
_______________________________________
SCCM Client Installation
net stop ccmexec
C:\windows\system32\ccmsetup\ccmsetup.exe /uninstall
copy \\10.10.10.10\uninstall\ccmdelcert.exe c:\temp
copy \\10.10.10.10\uninstall\ccmclean.exe c:\temp
copy \\10.10.10.10\uninstall\msxml6.msi c:\temp
c:\temp\msxml6.msi /quiet /norestart
cd \windows\system32\
RD /S /Q ccm
cd \windows\system32\ccmsetup
RD /S /Q ccmsetup.log
c:\temp\ccmdelcert.exe
c:\temp\ccmclean.exe /q
del %windir%\smscfg.ini /F /Q
\\10.10.10.10\e$\Softwares\Client\ccmsetup.exe/source:\\10.10.10.10\e$\Softwares\Client /mp:PrimaryServer.Domain.co.in SMSSLP=PrimaryServer.Domain.co.in SMSSITECODE=Sitecode FSP=PrimaryServer.Domain.co.in
________________________________________
ccmdel.bat
net stop ccmexec
C:\windows\system32\ccmsetup\ccmsetup.exe /uninstall
copy \\10.10.10.10\uninstall\ccmdelcert.exe c:\temp
copy \\10.10.10.10\uninstall\ccmclean.exe c:\temp
copy \\10.10.10.10\uninstall\msxml6.msi c:\temp
c:\temp\msxml6.msi /quiet /norestart
cd \windows\system32\
RD /S /Q ccm
cd \windows\system32\ccmsetup
RD /S /Q ccmsetup.log
c:\temp\ccmdelcert.exe
c:\temp\ccmclean.exe /q
del %windir%\smscfg.ini /F /Q
\\10.10.10.10\e$\Softwares\Client\ccmsetup.exe/source:\\10.10.10.10\e$\Softwares\Client /mp:10.10.10.10-PSS-01.domain.co.in SMSSLP=10.10.10.10-PSS-01.domain.co.in SMSSITECODE=ABC FSP=abc-PSS-01.domain.co.in
_____________________________________________
Below Batch file will Fix ,
–WMI rebuild Fix
–GUID Issue Fix
–MSXML not getting installed Fix
******************
net stop ccmexec
C:\windows\system32\ccmsetup\ccmsetup.exe /uninstall
copy \\10.10.10.10\uninstall\ccmdelcert.exe c:\temp
copy \\10.10.10.10\uninstall\ccmclean.exe c:\temp
copy \\10.10.10.10\uninstall\msxml6.msi c:\temp
c:\temp\msxml6.msi /quiet /norestart
cd \windows\system32\
RD /S /Q ccm
cd \windows\system32\ccmsetup
RD /S /Q ccmsetup.log
c:\temp\ccmdelcert.exe
c:\temp\ccmclean.exe /q
del %windir%\smscfg.ini /F /Q
–WMI rebuild
net stop winmgmt /y
c:
cd %systemroot%\system32\wbem
rd /S /Q repository
regsvr32 /s %systemroot%\system32\scecli.dll
regsvr32 /s %systemroot%\system32\userenv.dll
mofcomp cimwin32.mof
mofcomp cimwin32.mfl
mofcomp rsop.mof
mofcomp rsop.mfl
for /f %%s in (‘dir /b /s *.dll’) do regsvr32 /s %%s
for /f %%s in (‘dir /b *.mof’) do mofcomp %%s
for /f %%s in (‘dir /b *.mfl’) do mofcomp %%s
net start winmgmt
\\10.10.10.10\e$\Softwares\Client\ccmsetup.exe /source:\\10.10.10.10\e$\Softwares\Client /mp:PrimaryServer.Domain.co.in SMSSLP=PrimaryServer.Domain.co.in SMSSITECODE=Sitecode FSP=PrimaryServer.Domain.co.in
***********************
SUGGESTED HOTFIXES FOR WMI RELATED ISSUES ON WINDOWS PLATFORMS *UPDATED JUNE 14TH, 2012*
Individual deployment summary for specific application (AppModel EnforcementState)
select distinct
aa.ApplicationName,
ae.AssignmentID,
aa.CollectionName as ‘Target Collection’,
ae.descript as ‘Deployment Type Name’,
s1.netbios_name0 as ‘Computer Name’,
ci2.LastComplianceMessageTime,
ae.AppEnforcementState,
case when ae.AppEnforcementState = 1000 then ‘Success’
when ae.AppEnforcementState = 1001 then ‘Already Compliant’
when ae.AppEnforcementState = 1002 then ‘Simulate Success’
when ae.AppEnforcementState = 2000 then ‘In Progress’
when ae.AppEnforcementState = 2001 then ‘Waiting for Content’
when ae.AppEnforcementState = 2002 then ‘Installing’
when ae.AppEnforcementState = 2003 then ‘Restart to Continue’
when ae.AppEnforcementState = 2004 then ‘Waiting for maintenance window’
when ae.AppEnforcementState = 2005 then ‘Waiting for schedule’
when ae.AppEnforcementState = 2006 then ‘Downloading dependent content’
when ae.AppEnforcementState = 2007 then ‘Installing dependent content’
when ae.AppEnforcementState = 2008 then ‘Restart to complete’
when ae.AppEnforcementState = 2009 then ‘Content downloaded’
when ae.AppEnforcementState = 2010 then ‘Waiting for update’
when ae.AppEnforcementState = 2011 then ‘Waiting for user session reconnect’
when ae.AppEnforcementState = 2012 then ‘Waiting for user logoff’
when ae.AppEnforcementState = 2013 then ‘Waiting for user logon’
when ae.AppEnforcementState = 2014 then ‘Waiting to install’
when ae.AppEnforcementState = 2015 then ‘Waiting retry’
when ae.AppEnforcementState = 2016 then ‘Waiting for presentation mode’
when ae.AppEnforcementState = 2017 then ‘Waiting for Orchestration’
when ae.AppEnforcementState = 2018 then ‘Waiting for network’
when ae.AppEnforcementState = 2019 then ‘Pending App-V Virtual Environment’
when ae.AppEnforcementState = 2020 then ‘Updating App-V Virtual Environment’
when ae.AppEnforcementState = 3000 then ‘Requirements not met’
when ae.AppEnforcementState = 3001 then ‘Host platform not applicable’
when ae.AppEnforcementState = 4000 then ‘Unknown’
when ae.AppEnforcementState = 5000 then ‘Deployment failed’
when ae.AppEnforcementState = 5001 then ‘Evaluation failed’
when ae.AppEnforcementState = 5002 then ‘Deployment failed’
when ae.AppEnforcementState = 5003 then ‘Failed to locate content’
when ae.AppEnforcementState = 5004 then ‘Dependency installation failed’
when ae.AppEnforcementState = 5005 then ‘Failed to download dependent content’
when ae.AppEnforcementState = 5006 then ‘Conflicts with another application deployment’
when ae.AppEnforcementState = 5007 then ‘Waiting retry’
when ae.AppEnforcementState = 5008 then ‘Failed to uninstall superseded deployment type’
when ae.AppEnforcementState = 5009 then ‘Failed to download superseded deployment type’
when ae.AppEnforcementState = 5010 then ‘Failed to updating App-V Virtual Environment’
End as ‘State Message’
from v_R_System_Valid s1
join vAppDTDeploymentResultsPerClient ae on ae.ResourceID=s1.ResourceID
join v_CICurrentComplianceStatus ci2 on ci2.CI_ID=ae.CI_ID AND
ci2.ResourceID=s1.ResourceID
join v_ApplicationAssignment aa on ae.AssignmentID = aa.AssignmentID
where ae.AppEnforcementState is not null and aa.ApplicationName=’Adobe Reader XI 11.0.13′
order by LastComplianceMessageTime Desc
Silverlight WQL query for all Old Versions
https://www.microsoft.com/getsilverlight/locale/en-us/html/Microsoft%20Silverlight%20Release%20History.htm
silverlight_olderversions
Simple powershell to create a text file On C Drive using SCCM
To create the text file
Powershell.exe -Command "New-Item -path 'C:\Test' -name SCCM_Compliant.txt -type file -Force" __________________________ <a href="http://www.mssccm.com/wp-content/uploads/2016/12/up.txt">up</a>
and add a detection method to check under the folder “C:\Test” ..so that if the text file not present it will create it …