Get RDS-CAL License Details (2008 RDS License Server)

Get current RDS-CAL details via PowerShell. Run this from your 2008 RDS Licensing server.

# Filename of the export
$filename = RDS-CAL-Report.csv
# Import RDS PowerShell Module
import-module remotedesktopservices
# Open RDS Location
Set-Location -path rds:
# Remove previous reports (Optional)
remove-item RDS:LicenseServerIssuedLicensesPerUserLicenseReports* -Recurse
# Create new RDS report
$NewReport = new-item -path RDS:LicenseServerIssuedLicensesPerUserLicenseReports -Scope DOM -Name Report
# Name is automatically generated
$NewReportName = $NewReport.name
# Get issued licenses
$IssuedLicenseCount = get-item RDS:LicenseServerIssuedLicensesPerUserLicenseReports$NewReportNameWin2K8-Win2K8R2IssuedCount
# Count issued licenses
$IssuedLicenseCountValue = $IssuedLicenseCount.CurrentValue
# Get installed licenses
$InstalledLicenseCount = get-item RDS:LicenseServerIssuedLicensesPerUserLicenseReports$NewReportNameWin2K8-Win2K8R2InstalledCount
# Count installed licenses
$InstalledLicenseCountValue = $InstalledLicenseCount.CurrentValue
# Installed - Issued
$Available = $InstalledLicenseCount.CurrentValue - $IssuedLicenseCount.CurrentValue
# Show percentage available
$AvailablePercent = ($Available /$InstalledLicenseCount.CurrentValue)*100
$AvailablePercent = {0:N0} -f $AvailablePercent
# Display info
Write-host Installed: $InstalledLicenseCountValue
Write-host Issued: $IssuedLicenseCountValue
Write-host Available: $Available [ $AvailablePercent % ]
# Add the information into an Array
[System.Collections.ArrayList]$collection = New-Object System.Collections.ArrayList($null)
$obj = @{
Installed = $InstalledLicenseCountValue
Available = $Available
AvailablePercent = $AvailablePercent
Issued = $IssuedLicenseCountValue
Date = get-date
}
# Exit RDS location
set-location c:
# Create PSO Object with the data
$collection.Add((New-Object PSObject -Property $obj));
# Export Data into a file
$collection | export-csv $filename -NoTypeInformation -Encoding UTF8

Allscripts Vision User Reporting

A quick Powershell script I hacked together that will enumerate all Active Directory users, and build an XML file for an application I wrote that generates user reports for a specific application.

The output file format is similar to:

<quickreports>
  <report name=Organizational Unit>
  <database name=v001/>
  <usrlogin name=jdoe01/>
</report>
<quickreports>
$ErrorActionPreference= 'silentlycontinue'
$arr=@{}
foreach ($usr in Get-ADUser -Filter *  | select samaccountname) {
$user = get-aduser -identity $usr.samaccountname -ErrorAction SilentlyContinue
$userou = (($user.DistinguishedName -split =,2)[-1].split(,)[1] -split =,2)[-1]
$key = $userou
$value = $usr.samaccountname
if ($arr.ContainsKey($userou)) {
$arr[$userou] += $usr.samaccountname
} else {
$arr[$userou] = @()
$arr.add($key,$value)
}
}
$foo = <?xml version=1.0 encoding=utf-8?>`r`n
$foo += <quickreports>`r`n
$foo += foreach ($ou in $arr.keys) {
    write-output   <report name=$ou>`r`n
    foreach ($u in $arr[$ou]) {
                if ($u.contains(01)) {
                    write-output <database name=v001/>`r`n
                } elseif ($u.contains(04)) {
                    write-output <database name=v004/>`r`n
                } else {
                    write-output <database name=/>`r`n
                }
        write-output <usrlogin name=$u/>`r`n
}
    write-output </report>`r`n
}
$foo += </quickreports>
$foo | out-file quickreport.xml
# for some reason the outputted file was dumping 0x00 into the file.  Eventually
# I'll clean all this up and just write all the attributes and elements from up above
# but now is not the time as this is just a quick and dirty POC
$fn = quickreport.xml
$xmlDoc = [system.xml.xmldocument](get-content $fn)
$xmlDoc.save($fn)

Cleanup Windows User Temporary Files

This script will cleanup all users temporary files in their AppData\Local\Temp for Windows 7 and newer.

# Define the base directory for user profiles
$usersPath = "C:\Users"
$totalBeforeCleanup = 0
$totalAfterCleanup = 0

# Loop through each user folder in the Users directory
Get-ChildItem -Path $usersPath -Directory | ForEach-Object {
$userTempPath = Join-Path -Path $_.FullName -ChildPath "AppData\Local\Temp"
$userBeforeSize = 0
$userAfterSize = 0

# Check if the Temp folder exists
if (Test-Path -Path $userTempPath) {
# Calculate size before cleanup
$userBeforeSize = (Get-ChildItem -Path $userTempPath -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB
$totalBeforeCleanup += $userBeforeSize

# Remove all files in the Temp folder
Get-ChildItem -Path $userTempPath -Recurse -Force -ErrorAction SilentlyContinue | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue

# Calculate size after cleanup (to check if any files were in use and not deleted)
$userAfterSize = (Get-ChildItem -Path $userTempPath -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB
$totalAfterCleanup += $userAfterSize

# Output results for each user
Write-Output ("User: {0}`nSize before cleanup: {1:N2} MB`nSize after cleanup: {2:N2} MB`nCleaned up: {3:N2} MB" -f $_.Name, $userBeforeSize, $userAfterSize, ($userBeforeSize - $userAfterSize))
} else {
Write-Output "No Temp folder found for user: $($_.Name)"
}
}

# Output total cleanup summary
$totalCleanedUp = $totalBeforeCleanup - $totalAfterCleanup
Write-Output ("`nTotal size before cleanup: {0:N2} MB" -f $totalBeforeCleanup)
Write-Output ("Total size after cleanup: {0:N2} MB" -f $totalAfterCleanup)
Write-Output ("Total cleaned up: {0:N2} MB" -f $totalCleanedUp)

Quickly Check Domain Computers (Servers) for MS17-010 Patches

I put this script together from a few different sources.  It basically enumerates Active Directory and checks any 2008+ server for existence of KB patch for MS17-010.
MS17-010 patches a critical vulnerability discovered in Microsoft Windows operating systems that involve SMB exploits from a ShadowBrokers NSA dump of leaked NSA hacking tools.  It’s been spreading from CPU miner payloads to Ransomware (WannaCry/WannaCry 2.0) etc.

import-module activedirectory
$ErrorActionPreference= 'silentlycontinue'
# *** SERVER VERSIONS ***
# Server 2016 / Win10 - NT 10
# Server 2012 R2 / Win8.1 - NT 6.3
# Server 2012 / WIn8 - NT 6.2
# Server 2008 R2 / Win7 - NT 6.1
# Server 2008 / WinVista - NT 6.0
# Server 2003 R2 / WinXP64 - NT 5.2
# Server 2003 - NT 5.2
# WinXP - NT 5.1
$computers = get-adcomputer -filter * -properties * | select-object name,operatingsystem
$computers | foreach {
 $hotfixes = @()
 $osdetect = $_.operatingsystem
 $computer = $_.name
 switch -wildcard($osdetect)
 {
 "*Server*2016*" { $hotfixes = @("KB4013429", "KB4019472", "KB4015217", "KB4015438", "KB401663") }
 "*Server*2012*R2*" { $hotfixes = @("KB4012216", "KB4015550", "KB4019215") }
 "*Server*2012" { $hotfixes = @("KB4012217", "KB4015551", "KB4019216") } # A bit of a hack, not sure how this displays...
 "*Server*2008*" { $hotfixes = @("KB4012212") }
 default {$hotfixes = NULL } # Do nothing if it isn't a server and not 2008-2016.
 }
 if ($hotfixes.count -gt 0) {
 $hotfixes | foreach {
 write-host "Checking $computer ($osdetect)..."
 if (!(get-hotfix -id $_ -computername $computer)) {
 write-host $computer "Missing ($_)"
 }
 }
 } else {
 write-host "Skipping $computer ($osdetect)..."
 }
}

Powershell logparse regexp to csv

Input line:

Thu 2017-03-30 00:00:07: user@domain.com (John Doe) checked mail from 127.0.0.1 using IMAP, 0 msgs collected, 21 remaining

Powershell script:

$rxp = "([a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)|(d{1,3}.d{1,3}.d{1,3}.d{1,3})|(POP|IMAP)|(^[A-Z][a-z]+sd{4}-d{2}-d{2}sd{2}:d{2}:d{2})"
gc ".*.log" | select-string -pattern $rxp -allmatches | foreach {
if ($_.Matches.count -ne 4) {
return
}
[pscustomobject]@{
 'date'=$_.Matches[0]
 'email'=$_.Matches[1]
 'ipaddr'=$_.Matches[2]
 'proto'=$_.Matches[3]
 }
} | export-csv -notype analysis.csv