Category Archives: System Maintenance

Find GPOs with LoopBack Enabled

You can get a list of all Group Policy Objects (GPOs) with loopback very easily:


Get-GPO -All | Where { $($_ | Get-GPRegistryValue -Key "HKLM\Software\Policies\Microsoft\Windows\System" -Value UserPolicyMode -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Select -ExpandProperty Value) -eq 1}

This will query all GPOs and then conditionally return them if they have the value for UserPolicyMode set.

You could replace the “Get-GPO -all” with a filtered version if you were only interested in certain GPOs

A little longer version if you want to abstract it or modify it earlier:

Function GetLoopBack {
    param($gpo)
    $gpo | Get-GPRegistryValue -Key "HKLM\Software\Policies\Microsoft\Windows\System" -Value UserPolicyMode `
                               -WarningAction SilentlyContinue | Select -ExpandProperty Value
}

$GPOs = $GPOs | SELECT -Property *, @{Name='LoopBack';Expression={GetLoopBack2 $_}}

 

Advertisement

Querying the BitLocker SQL Database

Just a quick snippet to get all the Recovery Key’s for a specific user in the BitLocker database.

With MBAMRecoveryandHardware selected:

SELECT DomainName, u.Name Username, m.Name MachineName, k.LastUpdateTime KeyUpdate, VolumeGuid, RecoveryKey,RecoveryKeyId, Disclosed
  FROM [RecoveryAndHardwareCore].[Users] u 
  JOIN [RecoveryAndHardwareCore].[Domains] d ON (u.DomainId = d.Id)
  JOIN [RecoveryAndHardwareCore].[Volumes_Users] v_u ON (u.Id = v_u.UserId)
  JOIN [RecoveryAndHardwareCore].[Volumes] v ON (v_u.VolumeId = v.Id)
  JOIN [RecoveryAndHardwareCore].[Keys] k ON (v.Id = k.VolumeId)
  JOIN [RecoveryAndHardwareCore].[Machines_Volumes] m_v ON (m_v.VolumeId = v.Id)
  JOIN [RecoveryAndHardwareCore].[Machines] m ON (m.Id = m_v.MachineId)
  WHERE u.Name = '**username here**'

 

Finding Orphaned GPO Folders with PowerShell

During years and years of working in AD occasionally the sysvol folders gets out of sync with the actual GPOs. The following script will return all folders in sysvol\policies that no long have a corresponding GPO. **Please be sure to backup folders before taking any action based on this**

#Initial Source: https://4sysops.com/archives/find-orphaned-active-directory-gpos-in-the-sysvol-share-with-powershell/

function Get-OrphanedGPOs {
    

    [CmdletBinding()]
    param (
        [parameter(Mandatory=$true,ValueFromPipelineByPropertyName)]
        [string]$Domain
    )
    begin {
        $orphaned = @()
    }
    process {
        Write-Verbose "Domain: $Domain"
        # Get GPOs and convert guid into same format as folders
        $gpos = Get-GPO -All -Domain $domain | Select @{ n='GUID'; e = {'{' + $_.Id.ToString().ToUpper() + '}'}}| Select -ExpandProperty GUID
        Write-Verbose "GPOs: $($gpos | Measure-Object | Select -ExpandProperty Count)"
        
        # Get GPOs policy folder
        $polPath = "\\$domain\SYSVOL\$domain\Policies\"
        Write-Verbose "Policy Path: $polPath"

        # Get all folders in the policy path
        $folders = Get-ChildItem $polPath -Exclude 'PolicyDefinitions'
        Write-Verbose "Folders: $($folders | Measure-Object | SElect -ExpandProperty Count)"

        #compare and return only the Folders that exist without a GPO
        $gpoArray = $gpos.GUID
        ForEach ($folder in $folders) {
            if (-not $gpos.contains($folder.Name)) {
                $orphaned += $folder
            }
        }
        Write-Verbose "Orphaned: $($orphaned | Measure-Object | SElect -ExpandProperty Count)"
        return $orphaned
    }
    end {
    }

}

Running anything as a Service

You can use NSSM to run anything you want as a service very quickly.  In my case, I was looking to run AcuRite even when not logged in or while locked so that my weather station is always updating the cloud.

  1. Download NSSM and extract somewhere on your C Drive (i just put it in c:\nssm\
  2. Open a command prompt and change directories to where NSSM was extracted and run the following command (replace AcuRite with the name of the service you want to create)
  3. nssm.exe install AcuRite
  4. In the path field select the exe you would normally be running
  5. On the details tab set a description so you remember in the future why you created this.
  6. Click “Install Service”
  7. Start the service from the Services control panel

Easy and quick you now have AcuRite (or whatever you want) running as a service.

Setting a DHCP Option Value to Hex Bytes

So sometimes, some annoying times, you have a Vendor scoped DHCP option that you need to set and it is hex bytes. This can be quite frustrating as the GUI doesn’t provide an option to set the value (at least I haven’t found a way) and even when it does, you have to set it using the hex value. The second problem being, I don’t speak Hex.

The way I’d always done it before, and that comes up when I search for it right now uses netsh.

netsh dhcp server scope 10.200.100.0 set optionvalue 125 ENCAPSULATED 000003045669643A697070686F6E652E6D6974656C2E636F6D3B73775F746674703D3139322E3136382E312E313B63616C6C5F7372763D3139322E3136382E312E312C3139322E3136382E312E323B

This is fine if you already have the hex value, or the way to get it. It just isn’t idea if you want to do it for a ton of scopes, or if you don’t have the hex value.

Format-Hex will take a string and make it into an array of hex bytes nicely, so you can either use Powershell to produce that hex string

$hex  = [convert]::ToChar(0) + [convert]::ToChar(0)+ [convert]::ToChar(3) +  [convert]::ToChar(4) + "Vid:ipphone.mitel.com;sw_tftp=192.168.1.1;call_srv=192.168.1.1,192.168.1.2;"  | Format-Hex
$string = ($hex.Bytes|ForEach-Object ToString X2) -join ''

and Set-DhcpServerv4OptionValue will take that array and save it into the DHCP server for us, so you can then bulk setup scopes:

$hex  = [convert]::ToChar(0) + [convert]::ToChar(0)+ [convert]::ToChar(3) +  [convert]::ToChar(4) + "Vid:ipphone.mitel.com;sw_tftp=192.168.1.1;call_srv=192.168.1.1,192.168.1.2;"  | Format-Hex
Set-DhcpServerv4OptionValue -ComputerName dhcpserver -ScopeId 10.200.100.0 -OptionID 125 -Value $hex.Bytes

Replace the dchpserver with your actual dhcp server name, the scope ID would be the IP of the scope, etc… The nice thing in powershell is we can then script this and loop over scopes. Building the string per scope and setting it, which would be more complicated with the netsh version. Also sense it is in plain text instead of HEX it is far easier to read and update in the future.

We can reverse the process though it is slightly messier

$value = Get-DhcpServerv4OptionValue -computername dhcpserver -scopeid 10.200.100.0 -OptionId 125 
($value.value|ForEach-Object {[char][byte]"$_"}) -join ''

This will grab the value as an array of strings, in the form of “0x00”, convert that to bytes, then convert that to chars, then join it all back together into a string for viewing.

Finding VMs with IOPs Limiting Set

Using PowerCLI it’s pretty easy to find all the VM’s in your environment that have IOPs limits set.

get-vm | Get-VMResourceConfiguration | `
         Select VM -ExpandProperty DiskResourceConfiguration | `
         where {$_.DiskLimitIOPerSecond -gt 0} | `
         Select VM, DiskLimitIOPerSecond

This will give you a list of all VM’s where the IOps limits are not 0. You could change the condition to find VM’s with different disk shares, specific limits or any combinations there of.

Hope you find this useful 🙂

Setup Telegraf+InfluxDB+Grafana to Monitor Windows

Monitoring Windows with Grafana is pretty easy, but there are multiple systems that have to be set up to work together.

Prerequisites:

  • Grafana
  • InfluxDB

Main Steps:

  1. Create an InfluxDB database and users for Telegraf and Grafana
  2. Install Telegraf on Windows and configure it
  3. Setup a data source and dashboards in Grafana

It really sounds more daunting than it is

InfluxDB setup

We want to create an InfluxDB database,  create a user for telegraf to write data into influx, and a user for Grafana to read data out of influx.  From an SSH terminal, the commands will be

influx
CREATE DATABASE telegraf
CREATE USER telegraf WITH PASSWORD 'telegraf123'
CREATE USER grafana WITH PASSWORD 'grafana123'
GRANT WRITE ON telegraf TO telegraf 
GRANT READ ON telegraf TO grafana

Install Telegraf

You can go to https://portal.influxdata.com/downloads to get links download the client for different OS’s. Grab the link for windows, which at this time is https://dl.influxdata.com/telegraf/releases/telegraf-1.5.3_windows_amd64.zip and download that file using whatever method suits you best.   Extra the contents to a location you like,  I use c:\Program Files\telegraf\.  now you will need to modify the contents of telegraf.conf, I like to use Notepad++ but any text editor should be fine.

I like to modify the section called [global_tags] and put machine identifiers in there.

[global_tags]
 environment = "production"

You can add as many different tags under there as you would like, it takes some time to figure out what will be useful here.

When you have that completed, update the section for InfluxDB with the needed info. Make sure to update the IP and the passwords to the correct ones for your install.  Also if needed on the destination machine add the port 8086

# Configuration for influxdb server to send metrics to
[[outputs.influxdb]]
 urls = ["http://192.168.86.167:8086"] # required
 database = "telegraf" # required
 precision = "s"
 timeout = "5s"
 username = "telegraf"
 password = "telegraf123"

Now run a command prompt as administrator. Change to the directory where you have telegraf and its config file and run the following command to test your config:

C:\Program Files\telegraf>telegraf.exe --config telegraf.conf --test

The output should include a bunch of lines like the following:

 >win_perf_counters,instance=Intel[R]\ Ethernet\ Connection\ [2]\ I219-V,objectname=Network\ Interface,host=DESKTOP-MAIN Packets_Received_Errors=0 1522202369000000000
 > win_perf_counters,instance=Qualcomm\ Atheros\ QCA61x4A\ Wireless\ Network\ Adapter,objectname=Network\ Interface,host=DESKTOP-MAIN Packets_Received_Errors=0 1522202369000000000
 > win_perf_counters,instance=Teredo\ Tunneling\ Pseudo-Interface,objectname=Network\ Interface,host=DESKTOP-MAIN Packets_Received_Errors=0 1522202369000000000
 > win_perf_counters,objectname=Network\ Interface,host=DESKTOP-MAIN,instance=Intel[R]\ Ethernet\ Connection\ [2]\ I219-V Packets_Outbound_Discarded=0 1522202369000000000
 > win_perf_counters,objectname=Network\ Interface,host=DESKTOP-MAIN,instance=Qualcomm\ Atheros\ QCA61x4A\ Wireless\ Network\ Adapter Packets_Outbound_Discarded=0 1522202369000000000
 > win_perf_counters,instance=Teredo\ Tunneling\ Pseudo-Interface,objectname=Network\ Interface,host=DESKTOP-MAIN Packets_Outbound_Discarded=0 1522202369000000000
 > win_perf_counters,instance=Intel[R]\ Ethernet\ Connection\ [2]\ I219-V,objectname=Network\ Interface,host=DESKTOP-MAIN Packets_Outbound_Errors=0 1522202369000000000
 > win_perf_counters,instance=Qualcomm\ Atheros\ QCA61x4A\ Wireless\ Network\ Adapter,objectname=Network\ Interface,host=DESKTOP-MAIN Packets_Outbound_Errors=0 1522202369000000000
 > win_perf_counters,instance=Teredo\ Tunneling\ Pseudo-Interface,objectname=Network\ Interface,host=DESKTOP-MAIN Packets_Outbound_Errors=2 1522202369000000000

If it doesn’t, it should include error information that will help you determine what the issue is.  Once that works, you can then install telegraf as a service by running the following:

C:\Program Files\telegraf>telegraf.exe --service install

The service will not start automatically the first time however,  so then to start it run

net start telegraf

Now you should have telegraf collecting data from windows on a regular basis and dumping that data into InfluxDB, the only thing remaining is to graph it

Grafana Setup

In Grafana, set up a new data source.  It should look like the following:

teelgraf source

Once that is set up, then you can go create a dashboard and add a graph.  I created the following graph:

Windows CPU Graph

The query is:

SELECT mean("Percent_Processor_Time") FROM "win_cpu" WHERE ("host" = 'DESKTOP-MAIN' AND "instance" != '_Total') AND time >= now() - 5m GROUP BY time(500ms), "instance" fill(linear)

This basically tells InfluxDB to go get all of the win_cpu values where the host tag is set as “DESKTOP-MAIN” and the counter instance is not _Total.  For CPU values this means it gets the individual totals so that I can graph each CPU. Make that an equals instead and you’ll get just the overall CPU usage instead of the breakdown.

Then I group by tag(instance) which is how you get one line (or series) per CPU (performance counter).  After that, I use an alias by to make the name “CPU ” followed by the instance value.  If you don’t do that, you end up with some funky named series that just aren’t pretty to look at.   If anyone finds this interesting (or even if they don’t probably) I will make a post about how to use template variables to generate a whole dashboard of graphs for a whole set of hosts automagically.

This is a lot the first time you do it, maybe even the second.  But it really pays off and gives you some amazing ways to monitor computers and servers and pays off big in the end.

Finding Recently Updated Files

So I needed to find what log files were getting updated.  The files where inC:\ProgramData\VMware\vCenterServer\logs and that folder has many many folders and I wasn’t sure which one would have the files I needed. I was sure that they would have been updated recently.  So a quick little PowerShell to the rescue

Get-ChildItem -Recurse | Where {$_.LastWriteTime -gt (Get-Date).AddMinutes(-15)}

This returns all the files in the current folder and below that have been modified in the last 15 minutes.  It is easy enough to change up to look for other criteria, like *.log files int he last 5 minutes

Get-ChildItem -Recurse -Filter *.log | Where {$_.LastWriteTime -gt (Get-Date).AddMinutes(-5)}

Or all files with pid in their name

Get-ChildItem -Recurse -Filter *pid*

Powershell can be very very handy in a pinch! Hope this helps

 

Finding a VM by MAC address

Sometimes you only have a MAC address.   Whether you are starting from a DHCP log, or DNS entry, or some other source, occasionally you have less info than you would like.  If you find yourself with only a MAC address and a bunch of VMs to dig through then PowerCLI can help you find the machine you want.  It might also give you some tools to audit your environment and make sure everything is actually exactly as you expect it to be.

Once in PowerCLI and connected to VCenter a simple command will list all Network Adapters in our vCenter

Get-NetworkAdapter -VM *

It is then just a matter of filtering this output to match the MAC address we have:

Get-NetworkAdapter -VM * | Where {$_.MacAddress -eq "00:50:56:B2:2E:D9"}

Now that you have the adapter for the Virtual machine you want you can get the VM you want by expanding the parent attribute:

Get-NetworkAdapter -VM * | Where {$_.MacAddress -eq "00:50:56:B2:2E:D9"} | SELECT -expand parent | FT *

You now have all the attributes of the parent machine you could want, maybe just select Name, Host, and notes to narrow it down so you can get right to your target machine.

Get-NetworkAdapter -VM * | Where {$_.MacAddress -eq "00:50:56:B2:2E:D9"} | SELECT -expand parent | SELECT name, vmhost, notes

As a bonus, when using this method we can switch the where clause out and hunt for partial MAC addresses:

Get-NetworkAdapter -VM * | Where {$_.MacAddress -like "00:50:56:B2:*:D9"} | SELECT -expand parent | SELECT name, vmhost, notes

or if you want to find the IP address of the host you can use Get-VMGuest

Get-NetworkAdapter -VM * | Where {$_.MacAddress -like "00:50:56:B2:*:D9"} | SELECT -expand parent | Get-VMGuest

I hope this helps someone else in their time of night hunting down a rouge machine(s) 🙂

References:

http://terenceluk.blogspot.com/2013/11/finding-virtual-machine-in-vmware.html
https://www.vmguru.com/2016/04/powershell-friday-getting-vm-network-information/