Dynamic Groups in Azure AD – Windows 10/11

Dynamic Groups in Azure AD – Windows 10/11

Dynamic Groups in Azure AD is something that will change how you work. Inside my azure AD, I want a group for my windows 10 devices and a group for my windows 11 devices. Dynamic Groups allow you to set parameters for the members of that group. For example, if you want only Windows 10 devices, you select the build number. Want only Azure AD joined, add the parameter. So on and so forth.

Getting Started with Dynamic Groups in Azure AD

The first thing we need to do is log into azure. Click Groups on the left-hand side. Then Click all groups. Search for the group you want to make, just in case it’s already been built. Once you confirmed that it’s not the case, click “New Group”.

Here are the settings you will need to use:

  • Group Type: Security
  • Group Name: Windows 10
  • Group Description: All windows 10 machines
  • Membership Type: Dyanmic Device

Now you will need to click the Add Dynamic Query to add a custom query.

From here, we will click the Property and select DeviceOSType The operator is Starts With and Finally, the value will be Windows. We select these options for the first check because we only want windows devices. Macs start with “Mac”, Linux starts with the Version Number or the name of the OS type. While Windows always, and I mean always, Starts with Windows. Windows Server, Windows 10, Windows Vista, Windows 3.0.

Next, we need to click Add Expression. The And/Or needs to be set to And. So we are checking both queries. The property is going to be DeviceOSVersion, and the operator is going to be Start With. The value is important. As we have entered the world of Windows 11. Why is the value so important? It’s because Windows 11 is nothing more than a skin for windows 10 when it comes to the version number. Windows 11’s version number is 10.0.22000. While Windows 10 is 10.0.19… It’s super important for windows 10 groups to use a value of 10.0.1 with Start with. If you want only windows 11, use 10.0.2. I am expecting Windows 12 (currently in development) to be 10.0.3. Once you click the ok, You can check the members by clicking the Members tab on the left side of the Windows 10 group.

Windows 10 – 10.0.1
Windows 11 – 10.0.2

This group’s concept can be taken a few steps further. You can call out the windows version, and make groups accordingly. This will give some clearer auditing. This also will tell you what you need to update. I hope this helps out.

For more information about Dynamic Groups in Azure AD go here.

Install Sentinel One with Intune

Install Sentinel One with Intune

It’s time to Install Sentinel One. In this blog, we are going to go through the process of installing Sentinel One through Intune. We are going to be using the IntuneWinAppUtil program, and the MSI download of Sentinel one that you can obtain from your Sentinel one login portal. I will not go over how to download the msi installer.

File/Folder Structure

The next item you will need is the Microsoft Win32 Content Prep Tool [Link]. Once you have downloaded this file, I suggest creating a file structure as follows

  • Intune
    • Files
    • IntuneWin

After that, Extract the intunewinapputil.exe file to the top level of your file structure, intune. Place the MSI inside the Files location. Then we should be ready to run intunewinapputil.exe. Before you do, I always suggest reading the help by using the /? command line prompt. Here is the command we are going to use to convert our file.

Intune Win App Util

.\IntuneWinAppUtil.exe -c c:\Intune\Files -s SentinelOneInstaller.msi - o c:\Intune\IntuneWin

Afterward, we use the command above to convert our file into a intune installer file. This will give us a large amount of control. Things like detection rules, custom msi inputs and more. Which we will be using.

Intune – Setting up the installer

Next, It’s time to crack open the intune process. Log in to https://endpoint.microsoft.com/ with an account with intune rights.

Once you have logged into the endpoint management system. Click the Apps on the left-hand side of the screen.

Since we are deploying sentinel one to windows machines, under by platform, click the windows icon.

Uploading the Installer

Now we are going to click the add button on the right-hand side of the screen. This will bring up the add dialog box. We are deploying out the final option. Click the Windows App (Win32) option.

You will be brought to an upload page. Here you select the app package file and click the blue button on the right-hand side of the screen. This is where we go to the file we created in the previous steps. We upload the file here. Once it uploads it will populate the information like name and other items. Click ok to move to the app information page.

Setting the rules

Here we can change the name. Add a unique, html, description. Update the publisher, the application version and more. The category we are going to select is computer management. They show this as a featured app in the company portal. You want to check that one. This allows people to download this version of perch. If you want to feel in any of the other information you are welcome to. Once you have the required information, click next to go to the Program page. Where we determine how to install this application.

Adding the Key

On this page, we want to show the install and uninstall commands. This is where research comes into play. If you don’t know the silent install command of your program then that’s a problem. If you don’t know how your program responds to installs and the error codes or success codes it produces. that’s also a problem. You will need to know these things for other applications. Sentinel One is unique as it’s commands is a little different. Here is the install command:

msiexec /i "SentinelInstalle.msi" /q SITE_TOKEN="YourSiteToken"

Keep the uninstall command the same. As the MSI installer of Sentinel One is the app code. The biggest problem with the uninstall command with S1 is that it doesn’t work without prior approval. You have to log into the S1 Portal and approve its uninstall. Keep the default and continue.

Another thing to point out, this kicked my tail, the SITE_TOKEN does not have a /, I repeat NO /.

On this page, we can scan the system to make sure we meet the requirements. So if you know this is a heavy application, you can say to have at least 8GB of ram. You can even have PowerShell scripts that can trigger. A good example would be a user. If user Bob is on this PC don’t install it. The required items are the OS Arch and the minimum os. Which is going to be windows 10 1607 as that is intune’s min. Don’t get this confused with the next item. These are the requirements. Not meeting the requirements will prevent the app from installing. Once you have added what you want, click next.

On this page, we are going to select any dependencies that the application may need. Something unique about Sentinel One is, it will capture all of your custom PowerShell deployments. It’s best to set those as dependencies on this installer. This way they will deploy before S1 does. S1, doesn’t need any additional dependencies from my current knowledge and testing.

Detection Rules

We are going to use a Powershell Script to validate the install. Click on the Rule Format and select Use Custom Detection script. Upload your script file using the blue folder icon.

$A = 0
do {
    try {
        $Services = Get-Service -name SentinelAgent
    }
    catch {
        $Services = $null
    }
    start-sleep -Seconds 30
    $A = $A + 30
} until (($null -ne $Services) -or ($A -ge 300))
if ($null -ne $Services) { Write-Host "Installed" } else { exit }

This script checks for the Sentinel Agent every 30 seconds after installation. Then it increases my timer, by 30. It finally stops at 300 seconds. If services are null, it just exits, and thus a failure is seen in intune. If it is installed, it exits with a string. This tells the system that the installation was successful. What I like about this part is, that if the edit needs to be done, it can be done at this point using PowerShell.

The next screen supersedence is where you can choose what will replace the application. This is a preview feature at the moment and the idea is for upgrades. The final section is the Assignment, this is where you will select a group of devices for S1 to deploy out to.

I hope this is helpful for everyone viewing this page.

Handle with PowerShell

Handle with PowerShell

Lets talk about Handle. Handle is an amazing program that allows you to see which program has access over a folder or file. This is a sysintel tool. Working with handle inside your powershell script is not a native thing. The first thing you will want to do is download handle.

We first create the folder we want handle to be downloaded in. In this case, the c:\temp folder will work. Notice we check first to see if it exists with the test path. We will continue this trend so we don’t have to go through the download and creation process repetitively.

if (!(Test-Path "c:\Temp")) { New-Item -Path "c:\" -Name Temp -ItemType Directory }

Now we test to see if handle has already been downloaded before. If not, we download it. We are going to be downloading the handled application from http://live.sysinternals.com/handle.exe All of the Sysinternals tools are on this website and you can programmatically download them at any time. We are going to save the handle.exe in our c:\temp folder we created a few seconds ago.

if (!(Test-Path "C:\temp\handle.exe")) {
        Invoke-WebRequest -Uri "http://live.sysinternals.com/handle.exe" -OutFile "c:\temp\handle.exe"  -UseBasicParsing -DisableKeepAlive
    } 

Now we have handle, it’s time to get a handle on handle inside PowerShell. As command prompt program it needs to be called from the command prompt. We want to capture the output. Thus, using something like start-process is out of the question and here is why. Start process starts another processes. It does not keep the process in the current window. Thus you can not capture that data without doing some PowerShell magic which may or may not work. So, what we do instead is use the cmd.exe itself. We will use the /c flag and then the path to the handle software.

$ProcessHandles = cmd.exe /c C:\temp\handle.exe -a -u "$FilePath" -accepteula

Let’s break this down a little more. We are starting the handle application with an -a. The A is dumping all the handle information. This is a ton of information. The -u shows the owning user name when searching for handles. So we are grabbing all the information and the user information. We want to do this because it gives us the programs as well. Then we give it the path of the folder we want. So we basically give it a target. Now we are pulling all the handle information from a target folder with the user name/process name. The final handle flag is -accepteula. This basically makes it more automated. We call the handle using the cmd.exe /c. This brings the command output into our terminal which we can capture by placing into the $processHandles. Bam, now we have a bunch of confusing string information. The next step is to parse this string. Here is what the string looks like:

Nthandle v4.22 - Handle viewer
Copyright (C) 1997-2019 Mark Russinovich
Sysinternals - www.sysinternals.com

WINWORD.EXE        pid: 14248  type: File          ACTIVEDIRECTORY\bolding  A34: C:\temp\Change Control.docx

Now we need to handle the handle strings. So we search each string for the file name or file path with a simple where-object. This should create an array of information.

$Handles = $ProcessHandles | where-object { $_ -like "*$FilePath*" }

In this case, we only have one, but we want to make sure it doesn’t break if there is more than one. So we start a foreach loop. We loop through each handle in our handles. Each handle loops like this:

WINWORD.EXE        pid: 14248  type: File          ACTIVEDIRECTORY\bolding  A34: C:\temp\Change Control.docx

They are split apart by spaces. So, what we are going to do is use the split features. We are going to then search each line for an *.exe as most programs are .exe at the end of the day. We could expand upon this, but we will leave it here at this level. Once we have the .exe we want to remove that .exe with the replace command. Here is what the code will look like so far.

foreach ($Handle in $handles) {
        $Process = ($handle.split(' ') | where-object { $_ -like "*.exe" }) -replace '.exe', ''
}

Notice how we pipe one command into another and then wrap it with the replace. Simple one-line power right there. From here we need to test if the $process is empty. We do this because if the file in question isn’t locked down, we don’t want to error out. So a simple, if null is not equal to process, is set. The goal is to push these items into a smart system that will kill the process. However, there is one item I have discovered over the years doing this that tends to get killed by going down this route and that’s explorer.exe. I have killed it more than once. This is why I place an exclusion for explorer.exe. To do this we just check if the name matches with another if statement. So here is what the code looks like so far for this loop.

$Tasks = foreach ($Handle in $handles) {
        $Process = ($handle.split(' ') | where-object { $_ -like "*.exe" }) -replace '.exe', ''
        if ($Null -ne $process) {
            if ($Process -notlike "explorer") {
                $Process
            }
        }
    }

Now, here is the fun part. We can kill these tasks from the script itself. All we have to do is loop it through and stop each process with a stop-process. I placed a kill switch in the parameters just for this. So, if the kill switch is true, then we loop through each task killing it. If not, then we just display the processes. It’s that simple. Here is what that code looks like:

if ($kill) {
        foreach ($Task in $tasks) {
            Stop-Process -name $Task -Force
        }
    } else {
        $Tasks
    }

It’s that time, let’s put it all together and make the script.

The Script

function Set-SHDLockedFileProcess {
    param (
        [String]$FilePath,
        [switch]$kill
    )
    if (!(Test-Path "c:\Temp")) { New-Item -Path "c:\" -Name Temp -ItemType Directory }
    if (!(Test-Path "C:\temp\handle.exe")) {
        Invoke-WebRequest -Uri "http://live.sysinternals.com/handle.exe" -OutFile "c:\temp\handle.exe"  -UseBasicParsing -DisableKeepAlive
    } 
    $ProcessHandles = cmd.exe /c C:\temp\handle.exe -a -u "$FilePath" -accepteula
    $Handles = $ProcessHandles | where-object { $_ -like "*$FilePath*" }
    $Tasks = foreach ($Handle in $handles) {
        $Process = ($handle.split(' ') | where-object { $_ -like "*.exe" }) -replace '.exe', ''
        if ($Null -ne $process) {
            if ($Process -notlike "explorer") {
                $Process
            }
        }
    }
    if ($kill) {
        foreach ($Task in $tasks) {
            Stop-Process -name $Task -Force
        }
    } else {
        $Tasks
    }
}
Enable/Disable/Reset MFA with Powershell

Enable/Disable/Reset MFA with Powershell

How does one enable, disable, and reset a user’s MFA in Office 365? I was surprised by how much is required for enabling MFA.

Enable MFA

The first thing we do is Get the User from the Get-MsolUser.

$user = Get-MsolUser -UserPrincipalName $UPN

Next, we create a Strong Authentication object using the New-Object.

$SAR = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement

Now the object is created, you can review the object by using the Get-Member command. This object has 4 properties and 4 methods. We can now edit the properties. We will edit the RelyingParty and state.

 $sar.RelyingParty = "*"
 $sar.State = "Enabled"

Now we place the edited items into the user’s account.

$sarobject = @($sa)
Set-MsolUser -UserPrincipalName $user.Userprincipalname -StrongAuthenticationRequirements $sarobject

The Script

$user = Get-MsolUser -UserPrincipalName $UPN
$SAR = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequiremen        $sar.RelyingParty = "*"
$sar.State = "Enabled"
$sarobject = @($sa)
Set-MsolUser -UserPrincipalName $user.Userprincipalname -StrongAuthenticationRequirements $sarobjec

Disable MFA

Disabling MFA is extremely easy compared to enabling it. It’s as simple as putting a blank object inside the strong authentication requirements flag.

Set-MsolUser -UserPrincipalName $user.Userprincipalname -StrongAuthenticationRequirements @()

Reset MFA

The last one is to reset the MFA. Microsoft created a commandlet just for this case. The command is Reset-MsolStrongAuthenticationMethodByUpn.

Reset-MsolStrongAuthenticationMethodByUpn -UserPrincipalName $user.Userprincipalname

I hope this helps out.

How to speed up your Computer

How to speed up your Computer

The goal of this blog is to show you a way to speed up a computer using basic software commands/programs. I use these daily and I have seen them work. Sometimes they don’t sometimes they do.

Disk Cleanup

Disk cleanup is a powerful built-in tool that allows you to clean up temporary files and whatnots. It’s a very surface-level tool. I tend to prefer tools like wise disk cleaner over this tool. In this tool you can clean up a full range of items:

Disk Cleanup has two modes. A mode for standard users and a mode for Admins. Of course, you have to have admin rights to run the admin side of the app. Disk cleanup starts in standard mode. You know it’s in standard mode by the lack of options and the button with the admin shield on it called “Clean Up System Files”.

Standard user Mode

  • Download Program Files
  • Temporary Interent Files (Edge and IE Only)
  • DirectX Shader Cache
  • Delivery Optimization Files
  • Recycle Bin
  • Temporary Files
  • Thumbnails

Clean Up System Files – Admin Mode

When you click the “Clean Up system files”, disk cleanup restarts with more options. These options down blow. They include things like windows update items.

  • Windows update Cleanup
  • Windows update log files
  • Downloaded program files
  • temporary internet files (only edge and IE)
  • DirectX Shader Cache
  • Delivery Optimization Files
  • Device Driver packages
  • Language resource files
  • The Recycling Bin
  • Temporary files
  • Temporary windows installation files
  • Thumbnails

Wise Disk Cleaner

The next tool is a disk cleaner as well, but it goes much further than the basic standard disk cleanup. This tool is called wise disk cleaner by the company called wise. They also make wise registry cleaner and more. This software will clean out the temporary files of all of your browsers, your windows, cookies, and much more. It’s repo of what it looks for is fairly large. What I like about wise is it is smart as well. It knows what can be dangerous and what is not. You can tell it to be dangerous as well.

Wise disk cleaner on startup.

All you have to do is click the scan and then clean up. It does everything for you. Along with the scan and clean-up, it also offers disk defragging for HHDs. The system slimming and advanced cleaner are tools for the more advanced user and I wouldn’t recommend using them if you are new to computers.

I personally like that wise has a portable version in the portable apps platform and all versions have command-line switches as well. Here is more useful information:

WIse Registry Cleaner

After I run the disk cleaner, I run the wise registry cleaner on computers. Whenever a program installs, updates add to and so on with the OS, the registry gets junky. This junk often times has pointers to dead ends and other items that slow down the system. It is important to clean up those bad pointers, especially after a windows update.

What I like about Wise Registry Cleaner is it offers backing up your system with a restore point and a registry back before it does anything. They know that something bad could happen. The app also offers different scan types. Fast, Deep, and Custom.

Wise Registry Cleaner Start Page

The next example is a deep scan of a system I was working on.

Wise Registry Cleaner Scan

Wise Registry cleaner also has command lines like the disk cleaner. Here is some useful links.

Command Line tools – SFC /Scannow

This tool allows you to quickly find issues with your OS. Missing files, missing registry keys, and more. It validates your internal OS settings. The command has to be run as an administrator.

SFC /Scannow

SFC has much more flags that you can run, but I will not cover them in this blog. That’s worthy of its own blog post. For more information, you can check out the Microsoft documentation here.

DISM Cleanup

Finally, you can use the DISM command to reach out to Microsoft itself and compare/repair your system. the /online flag tells dism to go online. The /cleanup-image opens up the cleaning process and the various commands after that repair different items.

dism /online /cleanup-image /checkhealth

This command checks the system for anything that might be corrupt or damaged. This one is a high level and it also checks itself. Basically lets make sure the tool works.

dism /online /cleanup-image /scanhealth

This command scans the system for missing files, damaged files, and much more based on the image from Microsoft. This one is much more in-depth than the checkhealth. This part takes some time and once complete, the system is ready for the next command.

dism /online /cleanup-image /restorehealth

This command takes the list from scanhealth and the online repository and repairs the OS image. Without this command, nothing is getting fixed. It’s also best to run this command last. If this process appears stuck at any point, that’s normal. Let it do what it gots to do.

Final thoughts

I have come across lots of computers recently where office updates have damaged the OS and left thousands of useless files lying around. Completing these tasks has brought new life into those computers. It doesn’t work all the time, but when it does, it’s awesome. Out of all of the systems I have worked with the number one issue I see the most is age. Most slow computers are due to the fact that the computer is 10 years old trying to run the latest and greatest. My suggestion for those machines is linux.

I hope these little tricks will help you in your day-to-day IT endeavors.

Resolve a Site name to Geo Location

Resolve a Site name to Geo Location

With everything that happened with Facebook yesterday, I began to wonder where does my query goes when I type in facebook.com. So, I did a few things and found out. The first thing I did was resolve the name facebook.com to an IP address, or group of IP addresses in this case with the command resolve-dnsname.

Resolve-DnsName -Name facebook.com

Then from there, I used the site, ip-api.com to pull the location information of the IP address. This awesome little site gives you city, state, country, zip codes, and even the ISP information of an IP address.

$Info = Invoke-RestMethod -Method Get -URI "http://ip-api.com/json/$IP"

That’s the base of the code that we will explore. It’s very straightforward, but I want to clean it up some. I want to make a Get GEO IP information and a Resolve DNSname to Geo IP. I want it to all work together even if there is multiple IP addresses and hosts names. So, lets start off with the scripts and break them down. This will contain two functions for what we are wanting.

Get-SHDGeoIP

function Get-SHDGeoIP {
    [cmdletbinding()]
    param (
        [parameter(Mandatory = $true)][ipaddress[]]$IPAddress,
        [switch]$Complete
    )
    foreach ($IP in $IPAddress) {
        
        $Info = Invoke-RestMethod -Method Get -URI "http://ip-api.com/json/$IP"
        if ($Complete) {
            $Info
        }
        else {
            [pscustomobject]@{
                IPAddress = $info.Query
                City      = $Info.city
                State     = $Info.regionName
                Country   = $Info.country
                ISP       = $Info.isp
            }
        }
    }
}

This script is going to pull the geo information for us. We start off with the parameters. We are testing the parameters to see if the IP address is an valid IP address. We do that with [ipaddress]. This tests for both IPv4 and IPv6. We tell it to be a array of IPaddresses with the [] inside of it. [ipaddress[]]. Just for cleaner fun, I have a switch for a complete information dump. This way

Since this is an array of IP addresses, we will start a foreach loop for each IP address in the array. We start the foreach loop by grabbing the IP information. If the user selected complete, we just dump the information we gathered to the user. if they didn’t select complete, we create a custom object with the IP address, city, state, country and ISP information.

Resolve-SHDDNSNameToGeoIP

Function Resolve-SHDDNSNameToGeoIP {
    [cmdletbinding()]
    param (
        [parameter(Mandatory = $true)][string[]]$Hostname,
        [switch]$Complete
    )
    foreach ($Name in $Hostname) {
        if ($Complete) {
            Get-SHDGeoIP -IPAddress (Resolve-DnsName -Name $Name).IPAddress -Complete
        }
        else { 
            Get-SHDGeoIP -IPAddress (Resolve-DnsName -Name $Name).IPAddress
        }
    }
}

The next function uses the previous function and combines it with Resolve-DnsName. We start off with a list of strings for our hostname parameter and our complete parameter. We start our loop like before of the host names. Then we use the Get-SHDGeoIP -IPAddress command with the Resolve-DnsName -Name and the link name. We then select the IP addresses which is an array. We place that array inside the Get-SHDGeoIP and bam, we have our information. Converting a hostname like Facebook.com to IP information.

With these two little scripts, you will be able to find quick information about a website and where it is being hosted. For example, this site is hosted in new jersey. I personally didn’t know that.

Let me know if you use this and how.