SCCM Application Dependency Graph / Tree

Sometimes we have very complicated apps we have to deploy and need to view the application dependency tree to help investigate failed deployments. I found the built in view in the SCCM console clunky, buggy and annoying. So I wrote a small script to query WMI, list app dependencies and then output this visually using graphviz dot language.

The first thing the script does is query all the apps on your site server WMI for a search term. It then displays a list of applications in a grid view. You then choose which Application you want to create a dependency graph for. Once you have chosen one, the script will recurse through all the dependencies and build a graph.

It’s still in its infancy, it doesn’t highlight AND / OR relations and may have some redundant code that needs tiding up… But I find it useful to demonstrate to support staff why some applications take a while to deploy due to the complexity and amount of pre-reqs required!

  • Install graphviz for windows from here
  • Add an entry in your PATH environment varibale to the location of dot.exe – on Windows 10 for me it was : “C:\Program Files (x86)\Graphviz2.38\bin”
  • Download the script from Github Gist Here
  • Edit the variables in the script
    • $server – should be the management point server with the WMI Provider for your SCCM Site
    • $sitecode – should be the sitecode for your site
    • $graph_filetype – filetype of the output (I’ve only tested png, svg and pdf so far…)
    • $query – should be an application search string, the first thing the script will do is search and list the applications found using this. You can then choose which app you want to see the dependency tree for.
  • Run the script!
  • You should get two output files in the output directory
    • AppName.gv
    • AppName.(pdf/png/svg – depending on selected output filetype)
An example output png from the SCCM App Dependency Graph script.
An example output png from the SCCM App Dependency Graph script.

 

Advertisements

Checking SCCM Task Sequence Variables using Powershell

While running an OSD task sequence you can use powershell to check the TS Environment variables.

I added a ‘Pause’ step using this guide. If, like me, you are using an x64 PE image, you need use the ‘serviceui.exe’ from either the Program Files location on the machine with MDT installed, or a MDT package :

%MDTInstallLocation%\Templates\Distribution\Tools\x64\
%MDTPackage%\Tools\x64\

Once you have your Task Sequence paused, you can press F8 (if enabled in the boot image) and start powershell.

$env = New-Object -COMObject Microsoft.SMS.TSEnvironment

This will create an interface to the com object we need to use to interact with the TS environment.

$env.GetVariables() | % {$_ + "=" + $env.Value($_)}

This will dump out all the variables to the screen, this is a bit messy as there are lots of variables – some with quite long xml text as the values.

This will output all the variables to a text file :

 
$env.GetVariables() | % {$_ + "=" + $env.Value($_)} | out-file "variables.txt"

This will display the value of a specific variable (e.g. Architecture):

 
$env.Value("Architecture")

You could adapt this into a script to run automatically, instead of manually if required.

OneGet – Powershell Package Management

I have been writing a script to gather some permission information from out main Data drives. We have a lot of paths longer than 255 characters. Powershell’s default Get-Acl cmdlet cannot handle long file paths and errors.

Whilst looking for a solution, I came accross this .NET library which is supposed to help with issues related to long file names.

Microsoft.Experimental.IO

Considering I found it on nuget.org and I’m running Windows 10 (Windows Management Framework v5) I thought about using the new built in package management tool – previously called OneGet. The idea is simple – copy the linux package managers. Great, its just what Windows has needed always! I am not going to fully explain the concept behing a packagement tool in this post. This post has a great explanation.

So how do we install this Experimental library from Nuget.org? First, I tried the following command :

Install-Package Microsoft.Experimental.IO
Install-Package : No match was found for the specified search criteria and package name 'Microsoft.Experimental.IO'.
At line:1 char:1
+ Install-Package Microsoft.Experimental.IO
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Microsoft.Power....InstallPackage:InstallPackage) [Install-Package], Exception
    + FullyQualifiedErrorId : NoMatchFoundForCriteria,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackage

Hmmm, I guess the nuget repository isn’t loaded by default – how do we load a repo? Register-PackageSource https://technet.microsoft.com/en-us/library/dn890701.aspx Got a bit lucky here, the example at the bottom of the TechNet documentation for this cmdlet is how to load the nuget repo. I made one change, only a fool would use http instead of https.

Register-PackageSource -Name Nuget.Org -Location https://www.nuget.org/api/v2 -ProviderName nuget

Name                             ProviderName     IsTrusted  IsRegistered IsValidated  Location
----                             ------------     ---------  ------------ -----------  --------
Nuget.Org                        NuGet            False      True         True         https://www.nuget.org/api/v2

Now the repo is loaded we can install the Experimental.IO library. I ran the following command to list the packages containing “experimental”

find-package -contains Experimental | out-gridview

find-package-experimental-io

Converting VMware Machine to Hyper-V

As described in a previous post, I have installed MediaWiki on Server 2012 R2 Core. Now I need to convert the machine I built from ESXI to Hyper-V.

I needed to keep the original VM, with its Snapshots, and create a copy of it for a LAB environment. My setup :

  • ESXi (Free) 6.0.0 – Source
  • Server 2012 TP4 with Hyper-V – Destination

Steps I used to copy the VM :

  • Take a Snapshot of the Virtual Machine as a backup
  • We need a machine without snapshots to import into Hyper-V
  • Task Snapshot of functioning machine
  • Run “sysprep /generalize /oobe /shutdown” to generalize the machine and shut it down
  • sysprep

  • Use Vmware converter to convert machine from ESXI format to Workstation format (this will consolidate the snapshots, but leave the original VM untouched)
  • Download and install Microsoft Virtual Machine Converter (I used chocolatey to get MVMC)
  • Once conversion is finished you should have a vmdk and a vmx file in a folder.
  • Using the GUI of Microsoft Virtual Machine Converter it’s not possible to convert this ‘offline’ machine
  • We need to use powershell :
  • Import-Module 'C:\Program Files\Microsoft Virtual Machine Converter\MvmcCmdlet.psd1'
    ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath "C:\PathToVMDK\disk.vmdk" -DestinationLiteralPath "C:\DestinationFolder\" -VhdType DynamicHardDisk -VhdFormat Vhdx
    Disable-MvmcSourceVMTools -DestinationLiteralPath "C:\DestinationFolder\disk.vmdk"
    
  • Now, create a new VM in Hyper-V manager, I used gen 1 as my ESXI machine was using legacy / bios firmware. You may need to use Gen 2 if the original VM was running in UEFI mode.

I was pleasantly surprised by how quick and easy this was – whenever I have tried to do VM conversion in the past its never worked correctly!!

Enable .NET 3.5 In Windows 10 With Powershell

Depending on how you installed Windows 10, in order to enable .NET 3.5 features you may need to use an alternative source location. (The ‘sources’ folder from a W10 ISO file)

Run Powershell as Admin
powershell_admin
Run the following command (replacing the path with the path to your extracted or mounted ISO):

Enable-WindowsOptionalFeature -Path "D:\ISO\Windows\Desktop\Windows 10 Ent\SW_DVD5_WIN_ENT_10_64BIT_English_MLF_X20-26061\sources" -FeatureName NetFX3

command
net35_result

EDIT

I had an issue running this command today, and had to use dism instead to install the feature :

dism /online /enable-feature /featurename:NetFx3 /all /source:E:\sources\sxs

 

Collecting Custom Properties / Fields Using the Registry and Hardware Inventory

I recently implemented a mechanism for collecting warranty end dates using a script which added the date to a registry key, then using hardware inventory to collect the key into SCCM SQL DB.

This is useful if there is information about a client machine which is not stored in WMI.

It worked great and proved a good method of collecting data, In this post i will cover the whole process in detail :

Step 1 – The Script

The first stage is creating a powershell, vbscript or bat file to grab the custom property you are looking for and write it to a registry key. I won’t go into the detail of doing that in this post. I am using a script which reads the setupact.log file in C:\Windows\Panther and returns whether the machine firmware is BIOS or EFI (UEFI) – then writes the info to a reg key. I couldn’t find a field in the registry or in WMI on Windows 7 which stores this information. (Hence the script and this post!)

Step 2 – The Deployment

The script needs to be deployed and run on every machines we want to collect information from. I find it easiest to create a source folder, place the powershell script in there and create a bat file ‘wrapper’ to call the powershell script and temporarily change the execution policy.

powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File "script.ps1" >> "%temp%\script.log"

For the detection method, use the following :

  • Setting Type: Registry
  • Hive: HKEY_LOCAL_MACHINE (or other if you are using different hive)
  • Key: SOFTWARE\CompanyName\YourKey (this is the key you have written your info too)
  • Value: NameOfKey
  • Data Type: String (or other if you are using different data type)
  • I used “This registry setting must satisfy the following rule to indicate the presence of this application”
  • Operator “Not equal to”
  • Value: <blank>

Sometimes my script would fail to gather the info required but would create the key with null value, i didnt want my detection rule to be satisified by this. (I know i was lazy and should have added more error checking the script! But this had the same outcome….)

Step 3 – The Mof File

Great! We have the info in the registry, but now we want to add it to the SCCM DB – for ease of querying and reporting etc…

This method was inspired by this brilliant post – https://sccmguru.wordpress.com/2014/04/24/hp-and-lenovo-warranty-information-in-configuration-manager-2012-r2/

I suggest using the methods described in the above post to create your MOF file and import the changes into ConfigMgr.

Step 4 – The Result

Once you have deployed the hardware inventory custom settings, the deployment has run on some machines and hardware inv has run you should have some results! If not, something is wrong, retrace your steps and check for mistakes…

ConfigMgr Distribution Point Priority

Using System Center – Configuration Manager 2012 R2 we recently had some issues with routing, iscsi interfaces and content distribution. We needed to speed up distribution to a specific distribution point for some corrupt packages in order to get software installed at an Office in the Middle East.

So we needed the content to ‘jump’ the queue. There are no options in the SCCM Console to change DP priority order (that I have found), but luckily Microsoft have provided a way of doing it.

Note : As noticed by flatfour67 in the comments this may not work for DP’s assigned to secondary sites.

The following PoSH (Powershell) will list your Distribution Points and the Priority Assigned to them.

$dpinfo = Get-WmiObject -Query "SELECT NALPath, Priority, SiteCode, TransferRate, Description FROM SMS_DistributionPointInfo" -Namespace "ROOT\SMS\site_SITECODE" -ComputerName "MP_ServerName" | select NALPath, Priority, SiteCode, TransferRate
$dpinfo | Out-GridView
## Yes it could be done on one line, but I like doing it this way. After i have closed the GridView window i am still able to access the data without having to query WMI on the server again...

Default priority is 200, anything lower has a higher priority (content will be sent here first) and vice versa. Available values are 1 -> 300.

So How Do I Change the Priority?

Continue reading “ConfigMgr Distribution Point Priority”