Mass enabling windows features via PowerShell

Recently I needed to add the SNMP service to a few hundred systems. There are few more involved methods for this via unattended installs with SCCM or batch scripted GPO-linked entries but if you want a quick and easy way how, try the below.

Target OS: Server 2008, 2008R2, 2012 and 2012R2

Source system was a 2012R2 box with the AD and ServerManager PowerShell modules installed

Import-Module ActiveDirectory
$myservers = Get-ADComputer -SearchBase "OU=My Servers,DC=liquidobject,DC=com" -Filter "*"
foreach($i in $myservers)
 $mysession = New-PSSession -ComputerName $
 Invoke-Command -Session $mysession {Import-Module Servermanager}
 Invoke-Command -Session $mysession {Add-WindowsFeature SNMP-Service}

Any server in the OU offline or running an unsupported os (ie Server 2003….we all have them) will throw an error. The above is pretty basic example on how you can install any Windows feature remotely. The remote PSSession and Invoke-Command methods allow you to perform any supported PowerShell command remotely.

In the event your running a legacy version of Windows, there are still options available. The limitation of the below is that it requires you to login to the given system and run the command with an administrative command prompt.

servermanagercmd.exe -install snmp-service
, , , , ,
October 16, 2014 at 1:59 pm Comments (0)

Monitoring Exchange 2010 for Spammers

When using Exchange as your outside facing transport servers in either a dedicated Edge role under 2010 or within a multi-role setup finding out when you have a spammer from within historically has been done via blacklist notifications. What if we can catch the spammers in the act? What if we can stop the spam midstream? As a side benefit, you’ll get notification if mail is backing up for other reasons as well…ie random email providers being offline or if you end up having routing issues.

$servername = Get-Content env:computername
$mail_sender = "$"
$mail_server = ""
$mail_recipient = ""
$mailreport_subject = "Script: $servername Message Queues"
#At what level do you want to be emailed?
$maxinqueue = 40
$body = ""

Add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue

function SendEmailReport

    $msg = New-Object System.Net.Mail.MailMessage $mail_sender, $mail_recipient, $mailreport_subject, $body
    $client = New-Object System.Net.Mail.SmtpClient $mail_server
    $client.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials

$i = 0
while($i -lt 29)
	$mymessages = get-message -resultsize unlimited	
	#$mysenders  = $mymessages | select-object fromaddress
	if($mymessages.count -gt $maxinqueue)
		$body = "Warning the current queue on $servername has exceeded the queue count of $maxinqueue and is currently at " + $mymessages.count
		$body += "`r`n"
		$body += $mymessages | out-string

		$body = ""
	$mymessages = $null
	write-host $i
	Sleep 60

The $maxinqueue variable is the real trick, at what level of messages in the queue is normal for your organization?

Then all that needs to be done is configuration of a simple scheduled task say run every 30 minutes, the scripting logic is configured to run in a loop to cover at the per minute within a 30 minute window.

, ,
July 11, 2013 at 9:04 am Comments (0)

Clearing old Print Jobs

When using Windows Server as a print server over time the queues eventually begin to fill up. Print jobs are sent one day when a printer is offline and days later after the printer is turned back on sometimes dozens of print jobs start coming from the printer. The other issue that arises is caused by this backup of print jobs, slowly the print server will use disk space until in space cases it just runs out. Here is a simple PowerShell script to clear up the stale print jobs.

$TooOld = (Get-Date).AddDays(-2)
Get-WmiObject Win32_PrintJob | Where-Object { $_.ConvertToDateTime($_.TimeSubmitted) -lt $TooOld } | Foreach-Object { $_.Delete() }

This can be setup as an easy scheduled task to take of ever needing to worry about this issue in the future.

, , ,
June 25, 2013 at 11:41 am Comments (0)

Runaway process checking

Recently I ran into an issue with PHP exhaustion on a Windows Server running IIS. In this scenario the PHP-CGI.exe process would continue to spawn additional instances as load on the server would increase but over time the application pool would struggle and begin to slow to a crawl. In the past I have seen other applications during various iterations of development run into the same issue where if you run into more than “x” instances of an application it is unhealthy or less than “y” instances it is not running properly.


$myprocess = "php-cgi"
$myserver = "WebServer"
$mydomain = ""
$mail_server = ""
$mail_recipient = ""
$toomany = 40
$waytoomany = 80

$mail_sender = "$myserver@$mydomain"
$mailreport_subject = "Script: $myserver $myprocess count"
$body = " "

function SendEmailReport
    $body = [string]::join([environment]::NewLine, ($body)) 
    $msg = New-Object System.Net.Mail.MailMessage $mail_sender, $mail_recipient, $mailreport_subject, $body
    $client = New-Object System.Net.Mail.SmtpClient $mail_server
    $client.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials

$mycount =  (Get-Process -Name $myprocess).count

if($toomany -lt $mycount)
	$body = "We have $mycount $myprocess processes, something is unusual."
	if($waytoomany -lt $mycount)
             IISRESET /STOP
             IISRESET /START
             $body = "We have $mycount $myprocess processes, IIS has been reset."

In this case we are sending an email notification to the fictional “support team” when more than 40 instances of the php-cgi process are running and in the event no one responds by the time 80 instances are hit the site is automatically bounced to ensure it’s availability.

The simple method for checking is the use of Task Scheduler and call up the script every 5 minutes, pretty simple yet effective.

, , , ,
May 11, 2013 at 7:30 am Comments (0)

Large exchange distribution automation

Exchange distribution groups are a very useful method for delivering email to a large number of clients, however every design has it’s limits. I needed to use a distribution list for a rotating number of users with a total count of close to 20,000 members. When looking at distribution groups with more than a few thousand entries causes scalability limits. Naturally I’d rather not have to manually load lists every night.

if(Get-Module -Name ActiveDirectory){}
else{Import-Module ActiveDirectory}

Write-Host "Loading employees"
$myusers = Get-ADUser -filter "*" -SearchBase "OU=Employees,DC=liquidobject,DC=com" -properties description | Select-Object samaccountname
Write-Host "Successfully loaded" $myusers.count "employee accounts."

$alpha = "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"
foreach($i in $alpha)
    $mygroup = "EmployeeSub_$i"
    $myoldgroupmembers = Get-AdGroupMember -identity $mygroup | Select-Object SamAccountName
    Write-Host "Group:" $mygroup "has" $myoldgroupmembers.count "members"
    $mycurrentusers = $myusers | where {$_.samaccountname -like "$i*"}
    Write-Host "We currently have" $mycurrentusers.count "which should be in this group"
    $mydiff =  Compare-Object -ReferenceObject $myoldgroupmembers -DifferenceObject $mycurrentusers -property samaccountname
    foreach($i in $mydiff)
        if($i.SideIndicator -eq "=>"){Add-AdGroupMember -identity $mygroup -members $i.samaccountname}
        else {Remove-AdGroupMember -identity $mygroup -members $i.samaccountname -confirm:$False}

The above provides a differential solution by splitting the single very large group into a series of 26 smaller, more manageable groups. Then we can wrap the 26 groups with a query-based distribution group for simplified delivery to clients using

new-DynamicDistributionGroup All_Employees -OrganizationalUnit "OU=My OU,DC=liquidobject,DC=com" -RecipientFilter {RecipientContainer -eq "OU=EmployeeGroups,My OU,DC=liquidobject,DC=com"}
, , ,
March 21, 2013 at 7:58 pm Comments (0)

Counter Intelligence via Palo Alto Networks

As an aside from most posts found here, I found a fair amount of unusual traffic recently.  Last week I ended up looking up some models of Palo Alto firewalls and even downloaded a smartphone application of theirs. Nothing really out of the ordinary until  this past Wednesday when I see a large influx of traffic to the site.

Site Hits

In the above graphic you can large influx of probing hits coming from Palo Alto Networks. I can only assuming per other farming tactics I’ve seen in the past the data flows as follows.

  1. You visit Vendor XYZ’s site
  2. Vendor XYZ parses their website logs looking for those users who are making multiple queries against the products portion of the company site
  3. Vendor XYZ performs a bot query hitting up the site client’s IP to see if there is a website and if contact information can be captured
  4. A followup script takes the results and if enough information is capture then is forwarded to the pre-sales department
  5. My phone rings

Really? Do you think I’ll buy a PA-5050 or PA-5060 because you cold-call me mysteriously after I visit your website?


, , ,
March 10, 2013 at 8:31 am Comments (0)

« Older Posts