Saturday, September 12, 2020

Detect ConfigMgr Restart countdown

 # Show Machine restart time by Matthew Hudson, MVP

Function Check-Registry ($Regkey,$Regvalue)

{

$Foundit = Get-ItemProperty $Regkey $Regvalue -ErrorAction SilentlyContinue 

if (($Foundit -eq $null) -or ($Foundit.Length -eq 0))

       {

            Exit           

       }

  }

Check-Registry ("HKLM:\SOFTWARE\Microsoft\SMS\Mobile Client\Reboot Management\RebootData","RebootBy")

$UTCEPOCH = Get-ItemPropertyValue -path "HKLM:\SOFTWARE\Microsoft\SMS\Mobile Client\Reboot Management\RebootData" -name RebootBy

$REstartseconds =  (Get-CimInstance -Namespace root\ccm\policy\machine\requestedconfig -ClassName CCM_RebootSettings).RebootCountdown

If ((Get-TimeZone).SupportsDaylightSavingTime) {$TOffset=3600}

$newTime = $UTCEPOCH + (Get-TimeZone).BaseUTCOffset.totalSeconds+ $TOffset + $REstartseconds

$UTCTime = (Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($newTime))

"$UTCTime UTC" 

$ClientLocaltime =  [System.TimeZoneInfo]::ConvertTimeFromUtc((Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($newTime)), (Get-TimeZone))

"$ClientLocaltime Client Local time "  





Tuesday, April 7, 2020

Finding Lost Boundaries

With everyone shifting around boundaries in ConfigMgr, I thought it would be a good idea to give you way to read the logs to see if you missed a boundary, or if a boundary was missed.

MP_Location.log is updated when clients check-in, this is how they know where they are located.
If you are missing a boundary then download files and tickets are generated.



MP_GetAssignedSite  (<ClientLocationInfo OnInternet="0"><ADSite Name="HOUSTON"/><Forest Name="foo.com"/><Domain Name="Hou.foo.com"/><IPAddresses><IPAddress SubnetAddress="123.15.20.0" Address="123.15.20.2"/></IPAddresses><BoundaryGroups BoundaryGroupListRetrieveTime="0001-01-01 00:00:00.000"/></ClientLocationInfo>, <BoundaryGroups BoundaryGroupListRetrieveTime="2019-02-08T13:34:09.770"><DOINCServers/></BoundaryGroups>)

CHandleLocationRequest::CreateReply failed with error (80004005).
MP LM: Message discarded


The error "CreateReply failed with error (80004005)" is a good indicator of a problem with a boundary.  Look at the line directly above this and you have the missing boundary.  This could be a Subnet or IP subnet missing.  If you are not discovering them automatically then you need to add it manually.  If you are discovering them automatically, review the schedule. 

This log and move very fast the more machines you have on the MP.  Using this information boundaries can be auto create and even a notification sent that a boundary was missing but it was created for you.




Wednesday, February 19, 2020

Windows as a Service: Forcing machine forward

Do you have a Windows as a Service strategy lined out? 
How do you are going to push the upgrades. 
Are you going to allow everyone to upgrade to any version or control it? 
What are you doing about special machines you cannot force due to software or process control, are they moving at the end of cycle? 
Are you tracking which machines are out of compliance?

I bet that last question made you think.  Many companies have not tracked their end of life for Windows 10 which can be found here:
https://support.microsoft.com/en-us/help/13853/windows-lifecycle-fact-sheet

Now you can create a CI and pull machines into a collection that will soon be end of life, use this to force a popup, Toast Notification, force the upgrade, etc...


Powershell:

CI Discovery script
Data type:String
------------------------------------------
 $Win10_Life = @(
                 ("1607","1703","1709", "1803","1809","1903","1909"),
                  ("4/9/2019","10/8/2019","4/14/2020","11/10/2020","5/11/2021","12/8/2020","5/10/2022") )

$CurentWindowsVer = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name ReleaseID -ErrorAction Stop).ReleaseID

$index= 0..20 | Where { $Win10_Life[0][$_] -eq $CurentWindowsVer }
if ($index -ge 0)
{
  # grab the end of life date for the OS version
  $EndofLifeDate= $Win10_Life[1][$index]

  #determine number of days left in life
  $EndofLifeDays = (New-TimeSpan -Start (Get-Date) -End $EndofLifeDate).Days

   #$EndofLifeDate
   #$EndofLifeDays

    If ($EndofLifeDays -lt 60) {"Upgrade"}
}

-------------------------------------------------------------
You can see there is a 2 Dimension array with the build numbers and the end of life date.  If you are running Pro then you will need to change these dates, these are for Enterprise/Education. 

 In the Compliance setting I use 
"The value returned by the specified script:"
Not Equal to
Upgrade

This can be run once a month or every 3 weeks on a machine.  It will pull the machine into the collection if it has less than 60 days. 

How do I create the collection?
In the baseline right click on the deployment
Select the Non-Compliant. 

This will create a collection of machines that are not running a supported version of Windows 10. 

Monday, January 27, 2020

Query Desktop Analytics data

Currently, there is not a rich report system for Desktop Analytics. Until that day comes you can use Azure Monitor or even Power BI to pull your data. First using query tools such as Azure Monitor You can reach this via the Azure Portal Monitor - > logs or Log Analytics Workspace -> Select Workspace -> Logs You will have a box where you can query your data

 



to the left you will have the listing of tables:

Notice the "eye" to the right.  This is similar to the right click in SQL where you can select the top 1,000 records only this will normally only pull the top 50 records for you understand the data.


Now that you are ready to query, let's query to find all our Deployment plans and then grab all the machines that are set to be in the pilot group, either via the global pilot that was recommended and you added them:


(MADeploymentPlan)
Should you have too many then use the following query
MADeploymentPlan
| limit 50


Find the machines in there pilot.  But only show the columns for the Device name, Family, Source and Pilot Status







MAProposedPilotDevices 
| where DeploymentPlanId  == "881ba*******************56c"
| project  DeviceName , DeviceFamily, Source, PilotStatus  



Source = Was it part of the Global Pilot or was it added via Desktop Analytics
Pilot Status.  = Is in the the pilot, recall you can exclude or replace with other machines.

Source is interesting because if necessary you can now export this list and add it to the Collection in ConfigMgr and your pilot for upgrades or any other pilot would be more efficient.

Since there is no export function in DA we are here with this list.

At the top of your query



You can now export this to a CSV...but WAIT THERE'S MORE!!!

Notice that is gives you the Power BI query too! So you can pull in and manipulate it also!!!