PowerShell Script: Retrieve all Office 365 URLs and IP Ranges

This week I took the Office 365 Performance Management course on the Microsoft Virtual Academy. If you have any plans using Office 365 I strongly recommend taking this course. One of the topics that was often highlighted is the importance of having all Office 365 URLs and IP Ranges configured on the outbound allow list. The Office 365 URLs and IP Ranges are documented here and the changes to the list are described here.

As part of my continuous PowerShell skill improvement activity, I thought I write a script to retrieve this information via PowerShell. Microsoft has stored  the URL and IP address information into tables on this page, but thanks to Lee Holmes Get-WebRequestTable script I could loop through the various tables that contain the URL and IP address range information stored on the page.

The Get-Office365URLIPInfo script can be downloaded from the Microsoft TechNet Gallery here.

 

When you run the script, you get a list of all URLs or IP Ranges and the related Service.

office365

Installing Software using Collection Commander

In the past days I had to provision a number of clients for testing purposes. A specific set of software also needed to be installed on these clients. At our company when deploying software to computers, the deployment for none mandatory software is always set to “Available” so that users can choose themselves when to install the software via the Software Center.

I did not want to logon to each machine and initiate the installation manually nor did i want to create a separate “required” deployment to install the software on these systems. Instead I wrote a few lines of PowerShell code and triggered them using collection commander. I must admit its a bit of a quick and dirty approach but it did the job in just a few minutes.

Let’s walk through this step by step.

Information about all software that is deployed to a client, whether installed or not installed, can be retrieved using the following PowerShell command:

Get-CimInstance -Namespace root/ccm/ClientSDK -ClassName CCM_Application

To find the information about a specific software, we can run a command as shown in the below example:

Get-CimInstance -Namespace root/ccm/ClientSDK -ClassName CCM_Application | Where-Object {$_.Name -eq “Enterprise Mode Site List Manager”}

The CCM_Application Class provides an install method that allows us to invoke the installation of a software that is deployed to a client.

The important parameters to specify the application are the ID and Revision for the other parameters we can set static values.

image

Get-CimInstance -Namespace root/ccm/ClientSDK -ClassName CCM_Application |
Where-Object {$_.Name -eq “Enterprise Mode Site List Manager”} | Select-Object id, Revision | fl

image

The command to install the software would be as following:

([wmiclass]’ROOT\ccm\ClientSdk:CCM_Application’).Install(‘ScopeId_EBBD055B-8ABE-408E-90C6-A1A30A1B65FD/Application_785decc4-16de-41e6-93f7-a6615f3bcfdc’, 6, $True, 0, ‘Normal’, $False)

Below is the final code I put together and executed through collection commander:

$sw = (Get-CimInstance -Namespace root/ccm/ClientSDK -ClassName CCM_Application | Where-Object {$_.Name -eq “Enterprise Mode Site List Manager”})
If ([string]::IsNullOrEmpty($sw.InstallState))
{
    “software not assigned to this computer”
}
Else
{
    If ($sw.InstallState -eq “Installed”)
    {
        “Software is already installed”
    }
    Else
    {
    ([wmiclass]’ROOT\ccm\ClientSdk:CCM_Application’).Install($sw.id, $sw.Revision, $True, 0, ‘Normal’, $False) | Out-Null
    “starting software installation”   
    }
}

 

SNAGHTMLb4528ee

SNAGHTMLb45883d

When all software is installed, we can do a final check by running the following command via Collection Commander:

(Get-CimInstance -Namespace root/ccm/ClientSDK -ClassName CCM_Application | Where-Object {$_.Name -eq “Enterprise Mode Site List Manager”}).InstallState

SNAGHTMLb476abe

PowerShell Script to Retrieve Internet Explorer Telemetry Data

During the past days I have been busy deploying the Internet Explorer Site Discovery Toolkit to our Internet Explorer 11 test clients. I will write about the deployment of the Toolkit in a separate post. Today I would like to share with you a PowerShell script I put together that allows you to retrieve the collected Internet Explorer Telemetry data from local or remote computers.

Internet Explorer Telemetry data is stored into the following WMI Classes

Namespace Class
root/cimv2/ietelemetry IESystemInfo
root/cimv2/ietelemetry IECountInfo
root/cimv2/ietelemetry IEURLInfo

When running the Get-IETelemetryURLInfo command against a target machine, the script retrieves all information from the above listed WMI Classes. To make reading the results a bit more comprehensive I have extended the information that is returned by the script.

image

ActiveXDetail


The ActiveXDetail property holds additional information about the detected ActiveX object. By default only the ActiveXGUID is stored within the ActiveXGUID property. The script loops through each stored ActiveXGUID and searches for a match in the $ActiveXlist that is included in the script and provides a descriptive name.

BrowserStateDesc


The BroswerStateDesc property translates the BroswerStateReason property Code.

0 Unitialized;
1 IntranetsitesinCompatibilityViewchecked;
2 SiteisonGroupPolicyCVlist;
3 AddedtotheCVlistbytheuser;
4 X-UA-Compatibleappliedtopage;
5 Setbythedevelopertoolbar;
6 FEATURE_BROWSER_EMULATIONfck;
7 SiteonMSCVlist;
8 SiteonQuirksGroupPolicylist;
10 WebPlatformversionsupplied;
11 BrowserDefault;

DocModeReasonDesc


The DocModeReasonDesc property translates the DocModeReason property code.

0 Uninitialized
1 MSHTMPADtracetagsforDRTs
2 Sessiondocumentmodesupplied
3 FEATURE_DOCUMENT_COMPATIBLE_MODEfck
4 X-UA-Compatiblemetatag
5 X-UA-CompatibleHTTPheader
6 CVList-imposedmode
7 NativeXMLParsingMode
8 ToplevelQMEFCKwasset,andmodewasdeterminedbyit
9 Documentmodeistheresultofthepage’sdoctypeandthebrowsermode
10 modesuppliedasahint(notsetbyarule)
11 We’vebeenconstrainedtoafamilycanonlyhaveasinglemode(notsetbyarule)
12 Webplatformversionsupplied;thereforealigndocmodetowebplatformversion
13 Toplevelimagefileisset,andmodewasdeterminedbyit
14 Feedviewermodedeterminesdocmode

ZoneDescription


The ZoneDescription property translates the Zone property code:

-1 Invalid
0 Local Machine
1 Intranet
2 Trusted
3 Internet
4 Untrusted

The ActiveX switch

When launching the script with the optional -ActiveX switch, the script returns detailed information about the identified ActiveX components.

image

Following is the full script. You can download this script from the Script Center Repository Retrieve Internet Explorer Telemetry Information (Get-IETelemetryInfo)

 

 

Group Policy Management expanding into MDM

During the Channel 9 session “Windows 10 Client Goodness with Joe Belfiore” (at 12 minutes 04 of the recorded session)  there was an interesting comment from Joe about Group Policy Management in Widows 10. If you’re dealing with Group Policy Management today, the following comments from Joe might be of interest.

What we’re trying to do in Windows 10. And here’s another case where you think of a core operating system that shares among a bunch of
different devices. Today many companies are using Group Policy to manage PCs and companies are using MDM systems as they are getting from
a wide range of vendors to manage their diverse populations of tables and phones and so on. Well with Windows 10 we want to make sure that
all of our customers can have the flexibility to pick the system that makes sense for them so we are going to continue to have terrific group
policy support for PC’s as you would expect but we are also going to enable MDM systems to manage PCs as well. So if you have an MDM system that you like and you are managing phones and tablets, you can use that MDM system and now manage your PCs as well.

So what this means is that with Windows 10, managing client settings will no longer be limited to just Active Directory based Group Policy Management but will also become possible using MDM.

How to solve “The RPC server is unavailable” when loading the ConfigMgr PowerShell Module

Since a few weeks, I received the below error message when importing the ConfigMgr module in PowerShell, but everything I ran afterwards worked fine, so I kept ignoring it for a while. image

But now it was about time to get rid of this annoying message. My friend Claude Henchoz gave me a hint a while ago that helped me solve the issue. Looking at the error message more closely, I noticed the name of our old meanwhile decommissioned POC environment for ConfigMgr 2012 R2.

image

As it turns out, when importing the ConfigMgr module in PowerShell it seems to check whether the registered Sites can be reached. What registered Sites? Well when you connect to a ConfigMgr Site using the ConfigMgr Console, it stores the information of the sites into the registry. HKEY_CURRENT_USER\Software\Microsoft\ConfigMgr10\AdminUI\MRU

Running the following PowerShell command lists all the Sites:

Get-ChildItem -Path “HKCU:\Software\Microsoft\ConfigMgr10\AdminUI\MRU”

It turned out that MRU item 3 had information stored about a Site that doesn’t exist anymore, so I deleted it using the following command:

REMOVE-ITEM -Path “HKCU:\Software\Microsoft\ConfigMgr10\AdminUI\MRU\3″

And gone was the error when importing the ConfigMgr module.

ToolTip: Collection Commander

Collection Commander

Hey there, today I’d like to talk about an awesome tool called Collection Commander. If you’re working with Microsoft System Center Configuration Manager you probably know Client Center. Now Client Center is also a very cool tool, but it only allows you to work on one client. Collection Commander allows you to do things on multiple clients at the same time. Oh and before I forget, Collection Commander is created by System Center MVP Roger Zander, the same guy who creates Client Center.

Just in case you are not using System Center Configuration Manager, don’t walk away. While Collection Commander plays nicely with the System Center Configuration Manager Console, it also works without it.

Installation

Installing Collection Commander is straight forward. Just go to the Collection Commander CodePlex page and click on the Download button. When the download has completed run the windows installer package cmcollctr_1.0.0.11.msi

Collection Commander by default installs itself into “C:\Program Files (x86)\Collection Commander for Configuration Manager”. We will look at the content of that directory later.

Integrating Collection Commander as Right-Click Tool in the ConfigMgr Console

As mentioned previously, Collection Commander runs perfectly without ConfigMgr, but can be integrated as a right-click tool for the ConfigMgr Console. To register Collection Commander as a right-click tool, open Collection Commander, go to Settings and then press the “Add Console extension” button.

image

Next time you right click on a collection, you’ll see the Collection Commander option.

image

When selecting a ConfigMgr collection, and then launching Collection Commander, then all computers in the collection are added to the Collection Commander Computer list.

The Basics

When launching the Collection commander either via the ConfigMgr Console or directly Collection commander first starts checking the client status. If you launched Collection Commander manually you have to enter the computer name manually or if you have an Excel sheet or text file with computer names, you can just copy paste them into the tool.

SNAGHTML114f87c0

Collection commander first pings the client and then starts collecting some basic health information.

Online states:
clip_image008= Machine is online, no error occured
clip_image010= Machine is online, but an error occured (like: unable to connect by using WinRM)
clip_image012= Machine is offline (no response from ping)

The health state on the main form:
clip_image014Reboot pending = There are pending File-rename operations, or SCCM requires a reboot.
clip_image014[1]Updates missing = ConfigMgr. approved updates are missing.
clip_image014[2]Install running = ConfigMgr Agent is installing updates.
clip_image014[3]Users online = one or more users are logged on interactively.

Client Requirements

To take full advantage of Collection Commander WinRM must be enabled on the remote clients. For more information about enabling WinRM I suggest you read Enable Windows Remote Management through Group Policy.

Using Collection Commander

Opening the right-click context menu shows some basic ConfigMgr tasks that you can initiate on one or multiple computers. I believe they are quite self-explaining so I won’t go further into this.

SNAGHTML114f505b

Next are the “Run PowerShell Code” and the “Client Center” options. Before looking at the “Run PowerShell code”, let me explain what he Client Center option does and share a little trick with you.

When selecting the Client Center option, Collection Commander launches another Tool called Client Center. I won’t go into the details here, as I assume that you are familiar with it already, and if not I strongly recommend you check it out, at least if you are using ConfigMgr.

By default Collection Commander launches the web based installer for Client Center, but if you have Client Center already installed, you probably want Collection commander to launch your locally installed version. To change this behavior you have to make a small modification to the “C:\Program Files (x86)\Collection Commander for Configuration Manager\CMCollCtr.exe.config” file.

Change the entry

<value>http://sccmclictr.codeplex.com/releases/clickonce/SCCMCliCtrWPF.application?{0}</value>

With

<value>C:\Program Files\Client Center for Configuration Manager 2012\SCCMCliCtrWPF.exe</value>

You have to restart Collection Commander for the change to take effect.

PowerShell, PowerShell

Roger describes Collection Commander as following “The tool is designed for IT Professionals to trigger PowerShell Scripts on a list of devices”.

When selecting the “Run PowerShell Code…” menu option, we get the following Window appears.

SNAGHTML114f15ac

Within each of the folders you find some useful commands that can be executed against the targeted computers.

SNAGHTML114ed7f1

Out of the box, the following scripts are included:

  • · Agent Service Restart
  • · Agent Service Start
  • · Agent Service Stop
  • · Check CM Agent Service
  • · Get cache size
  • · Get cached content size
  • · Get DNS suffix
  • · Get GUID
  • · Get HTTP port
  • · Get HTTPS port
  • · Get internet MP
  • · Get MP
  • · Get SLP
  • · Reset policy
  • · Set cache size
  • · Set DNS suffix
  • · Set HTTP port
  • · Set HTTPS port
  • · Set site code
  • · Set SLP
  • · Application Evaluation
  • · Hardware inventory full
  • · Hardware inventory
  • · Heartbeat
  • · Request machine policy
  • · Request user policy
  • · Reset Policy
  • · Update Evaluation
  • · Update Scan
  • · Install CM12 Agent
  • · AppV packages where content path is on a sepcifi server
  • · Count Packages not fully loaded and older than 30 days
  • · Count running AppV
  • · Delete Packages where content is on a specific server
  • · Start DCM Scan
  • · Free disk space
  • · Get logged on user
  • · Logoff All Users
  • · Restart enforced
  • · Get SCOM Agent version
  • · SetMaintenanceMode
  • · CanProgramRunNow
  • · CanUpdateRunNow
  • · Count missing updates
  • · Get status of KB
  • · Install all mandatory updates
  • · Fix DCOM Permissions
  • · Register common DLLs
  • · WMI Consistency check

Add your own Scripts

Extending Collection Commander with your own scripts is straight forward. Just go to the Collection Commander Scripts folder “C:\Program Files (x86)\Collection Commander for Configuration Manager\PSScripts” and there create a new Directory and copy your scripts into that folder.

Example: To add a script that checks the total disk space on drive C: create a script called Total DiskSize Drive C.ps1 with the following PowerShell code

(([wmi]”root\cimv2:Win32_logicalDisk.DeviceID=’C:'”).Size/1GB).ToString(“N2″)+”GB”

Next copy the file into the PSScripts folder.

“C:\Program Files (x86)\Collection Commander for Configuration Manager\PSScripts\Alex\System\Total DiskSize Drive C.ps1″

And there you go, the script is now included within Collection Commander.

SNAGHTML114e96fc

The results of the scripts are displayed in the Status Message column.

SNAGHTML114e54de

Running PowerShell Commands

If you have to run the same commands frequently, it makes sense to store them in a script, but you can also run PowerShell commands instantly. Just add the command directly into the PowerShell code Window and then click the Run button.

SNAGHTML114e1c8f

For more information about Collection Commander visit the page on CodePlex: https://cmcollctr.codeplex.com/ If you have any questions or feature requests post them on the Discussions page. https://cmcollctr.codeplex.com/discussions

Cheers

Alex

Use PowerShell to find all collections where the specified device has a membership

Yesterday I deployed a computer with ConfigMgr and then wondered why it got certain software installed. And so another script was born.

The Get-CMCollectionOfDevice command retrieves all collections where the specified device has a membership

image

The Script can be downloaded from here

 

Analysing the file content of Windows Installer files using PowerShell

A few weeks ago we have started with the preparation for introducing Microsoft Office 2013 and Internet Explorer 11. As with every introduction of new software it’s all about compatibility. During the course of testing applications we were informed that some of them caused an issue due to hard coded paths. Each application is going to be installed anyway so that application owners can conduct testing, but at the same time I thought, it would be nice if we could identify potentially affected applications upfront without having to go through an actual install.

Here’s an example of an application that has a hard coded path to Microsoft Office 2010. The Directory is defined as Office14 which translates to the Office 2010 Installation directory.
SNAGHTMLeaddfff

As most of you probably know, a Windows Installer file is a database that contains all the necessary information for the installation of an application. In order to query the files referenced within the Windows Installer database, we have to look at the following database tables.

Let’s start with the File Table. In the below example we see that this Application consists of two files. The File Table contains the following attributes: File, Component_, FileName, FileSize, Version, Language, Attributes and Sequence.

SNAGHTMLebbd2f5

To find out in which directory this file installs, we first have to look at the Component table which has the following attributes: Component, ComponentId, Directory_, Attributes, Condition and KeyPath.

SNAGHTMLebf68cd

To link these two tables, we use the FileName attribute of the file table and Component attribute of the Component table. So far we know that the file iPublish_.dotm.lnk is going to be stored into the STARTUP folder. Now we only need to find out where the STARTUP folder is going to be, so we are going to look at the Directory table.

SNAGHTMLec3abc6

And there it is, the STARTUP directory. But we still don’t know where the file is going to be stored, as we first need to resolve the other Directory entries. If you study the directory table for a while, you notice that there is some logic in here.

SNAGHTMLec5a08f

To link the Directory table with the File and Component data, we join the Component table Directory_ attribute with the Directory table Directory attribute. However this still doesn’t give us the information where the file is going to be stored on the system, unless we would try to resolve the various entries within the Directory table, that to be honest would end up in a complex script (at least for me).

But then I found this forum post on stackoverflow discussing how to resolve MSI paths programmatically by calling the CostInitialize and CostFinalize Actions. The result of calling these actions is that the full file paths are resolved.

So now that we know what pieces need to be tied together, let’s turn this into a PowerShell script. I had a few challenges here. When calling the Windows installer object to invoke the CostInitialize and CostFinalize actions directly from within the PowerShell script that contains the Get-MSIFileInfo function, the Windows installer session would not close. So had to launch this in a separate process and then process the results within the calling script. This is why you find a complete PowerShell script defined in the $launchmsiscript variable.

When running the function against one or multiple Windows installer databases, the results are exported into a text file containing the following attributes for each file.

MSIFileFullname
MSIProductName
MSIProductVersion
Manufacturer
MSIProductCode
File
Component
FileName
FileSize
Version
Directory
Directory_Parent
DefaultDir
TargetPath

Example:
image

The entire script can be downloaded from here

 

Use PowerShell to Troubleshoot Group Policy

While I was on vacation last summer Ed Wilson aka Microsoft Scripting Guy asked me if I would like to write a guest post for the Hey Scripting Guy Blog. Of course !! was my immediate response.

And here it is:
Weekend Scripter: Use PowerShell to Troubleshoot Group Policy

The script referenced can be downloaded from here
http://gallery.technet.microsoft.com/scriptcenter/Get-GPProcessingTime-a124aaf5

How to identify ConfigMgr collections that take long to refresh

I’ve put together the below PowerShell script this week to identify collections in ConfigMgr that require the longest time to refresh. If you ever experience a decrease in ConfigMgr collection update performance, you might want to run this script to find potential collections that have a long refresh duration.

 

Thanks to Roger Zander and Claude Henchoz for the SQL query to find these collections.