Saturday, January 30, 2016

Deploy Windows 8.1 to Windows 8 via SCCM

We have some Windows 8 devices that needs to be upgraded to 8.1.  There is no installer for IE 11 and support has ended on Jan 12, 2016.  I did some research regarding upgrades for enterprise deployment tools but came across only a few articles that said the same thing.  It would have to be refreshed through OSD or downloaded through the Microsoft App Store.

I came across a Technet article of all things that didn't even come up as a top results for this and had a short mention for enterprise customers using SCCM 2012 to deploy the upgrade using the Windows 8.1 install media.  They must have added that upgrade switch later on because of the limited choices enterprise customers to upgrade and it wasn't easily found on any other tech sites.

Here's the article for reference:

https://technet.microsoft.com/en-us/library/dn744271.aspx

The only applicable part for my scenario.


For organizations running Windows 8 Enterprise RTM, the Windows 8.1 update process is simply running the Windows 8.1 setup.exe with a few command-line switches. The switches used in this update scenario are commonly the following:
  • /auto:upgrade. Required switch that runs the update process with no user interaction.
  • /noautoexit. Optional switch. If something goes wrong during setup, wait for user input.
This means that if you have only a few machines to upgrade, or if you want to test upgrading a few machines, you can simply download Windows 8.1 Enterprise ISO and run the setup.exe /auto:upgrade command. For larger numbers, you probably want to automate the setup using System Center 2012 R2 Configuration Manager.
We're still on CM 2007 so I figured why not give this a try and if it works, we just saved a lot of time and resources, if not then it would have to refreshed or upgraded through some other means.
I have tested it successfully on an HP Elitebook 8440p and it upgraded w/o a hitch, I thought something went wrong when I couldn't connect to it 2 hours later but the next morning I tried again and it worked.  So even if they don't officially list CM 2007, I can verify that it works.  I'll have to re-run the upgrade to see what goes on and how long it takes.  The tablets are powered by Atom processors and have SSD so I'm not sure how long they will take.  The only issue with them besides their sites having low bandwidth is their drive is only 32GB and near full.  Deploying a 3GB install might not work if it requires a lot of space during the upgrade.
Looking at the execmgr.log it appears that the SCCM client was still working as it periodically re-ran the advertisements and provided a 0 status every few hours and stopped at 2AM with occassionally lines of system restarted in between.  I'm thinking CM 2007 could not accurately track the install from the command line.

An interesting "side effect" of the upgrade was that it generated 15 more resourceID entries in the DB.  It's all obsolete but didn't expect to see that.



Thursday, January 21, 2016

SCCM Reporting: All Succeeded or Reboot Pending Status from advertisements using a specific package

We are progressing well with the IE 11 upgrade globally and all kinks are fixed for the most part.

Here's a query I use have used often when looking at the overall deployments success status for a large deployment project such as this.   We have over 12000+ machines to deploy to and for this project it was done with care from all the incompatibility and other environmental things that's not set for IE 11 until after IE 11 is installed on the system.   So this came in handy again for advertisements from testing, pilot, and production deployments and there are still more to be created!

This is a sub-query that pulls the advertisements status of 'Succeeded' and 'Reboot Pending' from the advertisements IDs tied to the package you're using.  In this instance it's both IE 11 packages.


Code below:

SELECT     v_R_System.Name0, vSMS_ClientAdvertisementStatus.LastStateName, vSMS_ClientAdvertisementStatus.LastStatusTime,
                      vSMS_ClientAdvertisementStatus.AdvertisementID, v_Advertisement.AdvertisementName, v_Advertisement.CollectionID, v_Collection.Name,
                      vSMS_ClientAdvertisementStatus.LastStatusMessageID
FROM         vSMS_ClientAdvertisementStatus INNER JOIN
                      v_R_System ON vSMS_ClientAdvertisementStatus.ResourceID = v_R_System.ResourceID AND
                      ((vSMS_ClientAdvertisementStatus.LastStateName = 'Succeeded' OR
                      vSMS_ClientAdvertisementStatus.LastStateName = 'Reboot Pending') and vSMS_ClientAdvertisementStatus.LastStatusMessageID != '10040') INNER JOIN
                      v_Advertisement ON vSMS_ClientAdvertisementStatus.AdvertisementID = v_Advertisement.AdvertisementID INNER JOIN
                      v_Collection ON v_Advertisement.CollectionID = v_Collection.CollectionID
WHERE     (vSMS_ClientAdvertisementStatus.AdvertisementID IN
                          (SELECT     adv.AdvertisementID
                            FROM          v_Advertisement AS adv INNER JOIN
                                                   v_Package AS pkg ON adv.PackageID = pkg.PackageID INNER JOIN
                                                   v_Collection AS v_Collection_1 ON adv.CollectionID = v_Collection_1.CollectionID
                            WHERE      (pkg.PackageID = 'XXX00853') OR
                                                   (pkg.PackageID = 'XXX00854')))

Wednesday, January 6, 2016

Create Collections from CSV file in SCCM 2007

Here's a script I use often for when we do targeted global deployments, I've combined a create collection script with one that reads from a CSV from the MSDN sample here: https://msdn.microsoft.com/en-us/library/ms974559.aspx .

Saves a lot of time from not using the console.  It reads from a CSV file with Headers defined as "Name" and "CollectionID" saved to c:\csv folder with the file named collections.csv which you can change to your liking.

The collectionID is the parent collection that will be created under.  Why 2 columns?  I like to separate EU, APAC, North America into their own given.  You may need to have parent collection created a head of time to retrieve the CollectionID.

Chances are you are running this on a x64 machine, if so, execute using cscript from c:\windows\syswow64\ instead of c:\windows\system32 or you might get an ADODB error.  You should not need any MDAC components, I'm running this on a Windows 2003 server.

Script contents:

'On Error Resume Next
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H0001

Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")

Set objLoc =  CreateObject("WbemScripting.SWbemLocator")
Set objSMS= objLoc.ConnectServer(strSMSServer, "root\sms")
Set Results = objSMS.ExecQuery     ("SELECT * From SMS_ProviderLocation WHERE ProviderForLocalSite = true")
For each Loc in Results
    If Loc.ProviderForLocalSite = True Then
        Set objSMS = objLoc.ConnectServer(Loc.Machine, "root\sms\site_" & Loc.SiteCode)
    end if
Next
 

strPathtoTextFile = "C:\csv\"

objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
          "Data Source=" & strPathtoTextFile & ";" & _
          "Extended Properties=""text;HDR=YES;FMT=Delimited"""

objRecordset.Open "SELECT * FROM collections.csv", _
          objConnection, adOpenStatic, adLockOptimistic, adCmdText

Do Until objRecordset.EOF
    strColName=objRecordset.Fields.Item("Name")
    strParentID=objRecordset.Fields.Item("CollectionID")
    wscript.echo strColName & " " & strParentID
    CreateSCCMCollection
    objRecordset.MoveNext
Loop

Sub CreateSCCMCollection
Set newCollection = objSMS.Get("SMS_Collection").SpawnInstance_()

newCollection.Name = strColName
newCollection.OwnedByThisSite = True
path=newCollection.Put_

'the following two lines are used to obtain the CollectionID
'of the collection we just created
Set Collection=objSMS.Get(path)
strCollID= Collection.CollectionID
'now we create a relationship betwen the new collection
'and it's parent.

Set newCollectionRelation = objSMS.Get ( "SMS_CollectToSubCollect" ).SpawnInstance_()
newCollectionRelation.parentCollectionID = strParentID
newCollectionRelation.subCollectionID = strCollID
newCollectionRelation.Put_
End Sub

Tuesday, January 5, 2016

SCCM 2007 DCM using VBscript

I assume anyone reading this would already know about but may not have looked at other ways to set up a compliance item.

I have tried using Powershell which is much even easier to write and shorter but you will need to ensure your environment has the proper PS policies in place.   Since they will not budge on the PS policies I used VBScript.

In the script below, it is looking for the Encase agent service name and querying for 2 names depending on what OS it was installed on.  I also use a modified version to check on the service state for running or stopped.  I use this for all security applications for our retail environment to reduce any non-PCI compliant systems.

Script contents:

strComputer = "."

   Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
   Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Service where Name = 'enstart' or Name = 'enstart64' ")

   For Each objItem In colItems
      encasename=objItem.Name
      'encasestate=objItem.State
        Next

Select Case encasename
Case "enstart"
wscript.echo "Compliant"
Case "enstart64"
wscript.echo "Compliant"
Case Else
wscript.echo "Non-Compliant"
End Select

Monday, January 4, 2016

Remove packages from DP from SCCM 2007 using Powershell

Here's a script to remove all packages from a DP in 2007 scheduled to be decommissioned.  I'm aware of the cmd-lets that are available for this but unfortunately Windows 2003 R2 can only have PS v2 and internal firewall rules prevents me from running this from a remote 2008 R2 servers, this is what I have come up with a variation of what I found of adding a package to a DP but instead to delete.

$ErrorActionPreference = "SilentlyContinue"
$SCCMServer = ''YourSCCMSERVER"
$SMSSitecode = "YourSiteCode"
$DP = "YourDP"

$pkgs = Get-WMIObject -ComputerName $SCCMServer -Namespace "root\sms\site_$SMSSitecode"  -Query "Select * From SMS_DistributionPoint WHERE ServerNalPath like '%$DP%' and SourceSite = '$smssidecode'"
foreach ($pkg in $pkgs){write-host $pkg.PackageID;$ID.Delete()}

If you want to find out the ServerNalPath of the servers replace the code with the below.  If you have PXE shares, you may end up accidentally deleting something you don't want but those shares shouldn't be holding software packages.  Enter a packageID to limit the results or it will pull the ServerNALPath from all packageIDs.

$pkgs = Get-WMIObject -ComputerName $SCCMServer -Namespace "root\sms\site_$SMSSitecode"  -Query "Select * From SMS_DistributionPOint WHERE PackageID = '$packageid' and SourceSite = 'XXX'"

foreach ($pkg in $pkgs){write-host $pkg.ServerNalPath}

Replace XXX with your site code above.

Good resources for scripting in general and SCCM related.

https://technet.microsoft.com/en-us/scriptcenter/bb410849.aspx

https://msdn.microsoft.com/en-us/library/cc145334.aspx

Monday, December 28, 2015

Deploying IE 11- IEAK vs Script

We are nearing our deployment deadlines for IE 11 and have come across a few options from MS to use.  I'm surprised this script here https://support.microsoft.com/en-us/kb/3061428 hasn't been widely known over IEAK.  We could have used use SCCM SUP but we wanted a more controlled method over Software Updates deployment.   We can pre-stage this ahead of time by setting up the advertisements in advanced due to low bandwidth connections in our retail environment.

The link is how to create a script to deploy an all-inclusive IE 11 package w/o needing to go to the internet to download any missing pre-reqs, language packs, and dictionary.  You can also add the latest cumulative update at the end to ensure your clients are updated after restart.

Having used the IEAK it is no different than using the standalone package as it will still download what it needs.  I have packaged the pre-reqs using the IEAK but it still needs the language and dictionary packs.  Unless I built it wrong, I checked the temp folders and log and it still downloaded the pre-reqs, regardless it's not the all-inclusive package.  Our retail environment has POS devices that do not have internet access and is why this has failed on them.   Since the IEAK is a wrapper, regardless if it succeeds or fails, it will show as a "succeeded" in SCCM.  Using the script provides a more clear status including Pending Reboots.

If your environment is English only then you're ready to with what's on the link above.

A note for deploying both versions using dism, you may need to put the path and they are different in x86 and x64 Windows.  If you have already deployed IE 11, you can find the c:\windows\IE11_Main.log for the syntax used which is the same as in the link.

x86
C:\Windows\System32\dism.exe

x64
C:\windows\SysNative\dism.exe

For our environment, it didn't stop there.  We had to account for the various lang packs installed in the OS  in the images and various geographic regions through out the world.   Our global image standard used everywhere had 13 languages if a machine was imaged within the last 2 years.  If before that then it was only localized, if needed.

We tried to see if we can bundle all languages /dictionary packs for every language in our environment and see if that would work.  In testing, that did not and will roll back taking a few hours to become ready again.

With that failure it seems it would only work with what languages are already installed.  We had created a reg query in the script to only install what was found for the available language under the registry key below.  This has worked well for the latest and varied images with less lang packs.   The newer machines with 13 language packs to install has taken up to 30-40 minutes to install, English only takes less than 5 minutes.

Registry key for Install OS language packs
HKLM\SYSTEM\CurrentControlSet\Control\MUI\UILanguages\

If you have any failed installs you may want to run this to remove any current packages and retry it after a restart.

FORFILES /P %WINDIR%\servicing\Packages /M Microsoft-Windows-InternetExplorer-*11.*.mum /c "cmd /c echo Uninstalling package @fname && start /w pkgmgr /up:@fname /norestart /quiet"

If you want to remove the language packs, run the command below as an example for Korean.  The /r suppress restarts and it is not quick to uninstall a language pack.

lpksetup /u ko-KR /r