AMoRPH.US: PowerShell Consulting 


PowerShell MVP Don Jones has a new article about the growing need for PowerShell consultants - PowerShell experts to help IT departments automate using PowerShell.

In the past few weeks, I’ve heard from a dozen or more organizations that are starting internal projects to automate specific tasks…

(Source: ihunger)

@2 years ago with 5 notes

Quest AD Cmdlets Giving Some Funky Errors

We ran this to reset some password expiry issues:

Import-Csv "Test.csv" | foreach {Get-QADUser -SamAccountName $_.SamAccountName | Set-QADUser -passwordNeverExpires $true}

but got nowhere and it didn’t change anything so I modded it to this thinking it’d just grab the user and change it:

Import-Csv "Test.csv" | foreach {Get-QADUser | Set-QADUser -passwordNeverExpires $true}

…but contrary to popular belief, the pipe just skipped passed and got the content from import-csv, but then changed EVERY user in the Get-QADUser command instead of just the ones asked… Weird, right? So we stopped it about 50 users in and copied the data to a text file to change back after we fixed the command like this:

$users=get-content test.csv
foreach ($user in $users) { Set-QADUser $user -UserMustChangePassword $true }

To fix the stuff we broke earlier, we used the Split() command as seen HERE.

@2 years ago

PowershellASP V3 Woes with Get-QADUser Cmdlet

So I installed the new fancy PowershellASP v3 today from to try out querying AD from a webpage, and with Win2008R2 you get the activedirectory cmdlets in Windows, so this will work (just a mod of the get-tweet sample code they’ve got, it’s not clean, but for testing purposes…)

      function Get-ldap { 
import-module activedirectory
       $query = $request['query'];
       if ($query -eq $null) { $query = "ASMITH" };
	get-aduser $query -properties *
      $finduser = Get-ldap;

and it gives me this result (and some more, but for the sake of showing):

Query: AccountExpirationDate : accountExpires : 9223372036854775807 AccountLockoutTime : AccountNotDelegated : False adminCount : 1 AllowReversiblePasswordEncryption : False BadLogonCount : 0 badPasswordTime : 0 badPwdCount : 0 CannotChangePassword : False CanonicalName : AWEBSITE.local/Users/ASMITH Certificates : {} City : CN : ASMITH codePage : 0 Company  : Country : countryCode : 0 Created : 12/22/2011 6:55:46 PM createTimeStamp : 12/22/2011 6:55:46 PM……….

However, in my production environment I’m not up to Win2008R2, so I’m filling in with the Quest ActiveRoles Cmdlets.  They do the same thing, but apparently not with PowershellASPV3 as this doesn’t work:

      function Get-ldap { 
add-pssnapin quest.activeroles.admanagement
       $query = $request['query'];
       if ($query -eq $null) { $query = "ASMITH" };
	get-qaduser $query
      $finduser = Get-ldap;

Super frustrating though and about to hang up the cleats. It gives me this error when run:

PowerShell get-ADUser Search

Enter a NT LOGIN name and get the LDAP attribs of that user. The template shows the use of the $request object to retrieve submitted form variables.


Get-QADUser  : Object reference not set to an instance of an object. At line:23 char:13 + get-qaduser «« $query -properties * + CategoryInfo : NotSpecified: (:) [Get-QADUser], NullReferenceEx ception + FullyQualifiedErrorId : System.NullReferenceException,Quest.ActiveRoles. ArsPowerShellSnapIn.Powershell.Cmdlets.GetUserCmdlet 

What gives here?  What am I missing?

@2 years ago

Searching Outlook with PowerShell « zeladinet 

Still trying to find a good way to use P$ as my search provider.  I know everything else is usually indexed, but would be a fun project…

@2 years ago

Remotely Logging Off a Machine in Powershell via Outlook Email

So this opportunity came up with this scenario:

  1. A retail employee would log on to an XP workstation. Yes, Win7 would solve all this, but Win7 is not deployed.
  2. The employee would go to lunch, take a break, whatever, and the workstation would lock as per the security policy after 5 mins.
  3. People would still need to make sales, and didn’t know the password of the logged in user.
  4. They’d reboot the box to resolve it, and that’d take 5-10 mins to reboot.
  5. Customer gets upset waiting so long.

So we brainstormed a couple ideas and I just put this one together to monitor a mailbox that’d force log-off anyone on that box based on the computer name entered in the subject line.

#this program will receive an email and log off the machine name in the subject line
#save the subject line and run the command based on it to shutdown/log off user on box
#(Get-WmiObject -Class Win32_OperatingSystem -ComputerName .).InvokeMethod("Win32Shutdown",4)
#force it to match the desktop (can't reboot servers and ONLY retail POS machines somehow 
#in the naming convention, or OU maybe?
#only allow if the from address is a certain address and can't be spoofed address
#check headers maybe to make sure it came from a valid address?

$olFolderInbox = 6 
$outlook = new-object -com outlook.application; 
$ns = $outlook.GetNameSpace("MAPI"); 
$inbox = $ns.GetDefaultFolder($olFolderInbox) 
$inbox.items | foreach { 
        if($_.subject -like "*WHATEVERFILTERYOUWANTTOKEYOFF*") {(Get-WmiObject -Class Win32_OperatingSystem -ComputerName $_.subject).InvokeMethod("Win32Shutdown",4)}

write-host "sleeping for 30 seconds to clean out the mailbox"
sleep 30

#Name of folder to access.  You can specify subfolders by using FolderName\Subfolder
$folderPath = "inbox"

#Filter older than 30 seconds
$olderThan = (get-date).Addseconds(-30)
#Set format of date to use 
$dateFormat = "g" # This will base on time to do just date choose "M/dd/yyyy"

#Create filter
$sFilter = "[LastModificationTime] < `'$($olderThan.tostring($dateFormat))`'"

$outlook = New-Object -ComObject Outlook.Application
$n = $outlook.GetNamespace("MAPI")
$f = $n.GetDefaultFolder($olFolderInbox)
$mailbox = $n.Folders.Item($f.Parent.Name)

$folders = $mailbox.Folders

#Navigate to the proper folder
foreach ($folderName in $folderPath.split("\"))
  $folder = $folders.Item($folderName)
  $folders = $folder.Folders


$FilteredItems = $Items.Restrict($sFilter)

for ($i = $FilteredItems.Count; $i -gt 0; $i--) { 
    Write-Host "Moving this out of Inbox: $($FilteredItems.Item($i).Subject)"

#Clean out any open connections
$outlook = $n = $f = $mailbox = $folder = $folders = $Items = $FilteredItems = $null;

NOTE: make sure you have Powershell V2.0 for this on all the machines you want to reboot or the “invokeMethod” command won’t enjoy you. Download it here:

@2 years ago

Different Ways to Use the Split() Command in Powershell

I had a scenario where we made some Active Directory changes via the Quest Get-QADUser command we wanted reversed because it didn’t act the way we thought it would.  We wanted to set the passwordNeverExpires tag on a few accounts, so we kicked around the info in THIS post.  

Essentially, we grabbed a bunch of users from the output screen that we needed to put back that looked like this:

ExchSVC                        user            CN=ExchSVC,OU=Service Accounts,DC=WEBSIE,DC=LOCAL
Guest                          user            CN=Guest,CN=Users,DC=WEBSITE,DC=LOCAL
jason                          user            CN=jason,CN=Users,DC=WEBSITE,DC=LOCAL

So here are a few ways of making magic with the Split command in Powershell:

#The [regex] expression “,*..=” says find a pattern that #matches zero or more commas any two characters and an equal sign. #This would match any of the following: cn= ,ou= ,dc=

$dumped = gc "dumped.txt" 
foreach($user in $dumped) 
($user -split ",*..=")[1] | out-file justSamAccount.txt -append
ii justsamaccount.txt

#or could split on just grabbing first line (notice the double spaces on the split #as some usernames have spaces and you don’t want to split on them

$dumped = gc "dumped.txt" 
foreach($user in $dumped) 
($user -split "  ")[0] | out-file justSamAccount2.txt -append
ii justsamaccount2.txt 

#could also use split another way and split on commas and equals signs and grab the line in question:

$dumped = gc "dumped.txt" 
foreach($user in $dumped) 
$user.split(",=")[1] | out-file justSamAccount3.txt -append

ii justsamaccount3.txt 

and I’m certain there are plenty more, but these are the ones I came up with to fix it.

@2 years ago

Active Directory Web Services Not Installed After DCPROMO

Yea, it’s weird - I was just messing around in a virtual environment I stood up and was going to try to move FSMO roles with Powershell.  The first thing to do was to make sure ADWS was installed as the command I needed was in that module.

ipmo activedirectory

Contrary to popular belief, that just gives me: 

I can’t imagine I’m the only person to ever see this, but Google apparently thinks so:

I ended up transferring them the old fashioned way, so not sure why it didn’t install, but will keep a closer eye on it next time to see if I clicked something else wrong along the way…

UPDATE:  I thought i’d check if it was the HPC version and just like that, there’s my answer:

@2 years ago

Use PowerShell to Data Mine Your Outlook Inbox - Hey, Scripting Guy! Blog - Site Home - TechNet Blogs 

@2 years ago

Don Jones Quote

Wouldn’t mind seeing it in action somewhere.  Got any examples of how you’ve used it?


From PowerShell MVP Don Jones

Remember my PowerShell Proverb: Every time you write a script that outputs text, God kills a puppy. It’s on your head.

WOW! At least he tells you how to avoid this fate.

(Source: powerwf)

@2 years ago with 1 note

Sending mail through PowerShell


function Send-Email
param($to, $from, $subject, $body, $smtpServer)
$msg = new-object Net.Mail.MailMessage     
$smtp = new-object Net.Mail.SmtpClient($smtpServer)          
  $msg.From = $from     
$msg.Subject = $subject
$msg.Body = $body           


Or use the new fancy send-mailmessage:

send-mailmessage -to "andy@AWEBSITEcom" -subject "The script took $timer3 to run" -body "
Script started at: $timer1
Script finished at: $timer2
It took $timer3 to finish." -smtpserver "MAILSERVERRELAYNAME" -from ""

(Source: henrikblog)

@2 years ago with 1 note