Category Archives: Scripting

Credentials Management in PowerShell

This blog is plagiarized from the best article I’ve ever found on this subject.  Full credit to Kris Powell for this amazing article found here.

Here are my condensed notes for my use.  If you find it useful, give a shout out to Kris Powell.

We now know how to convert a SecureString to an encrypted standard string. We can take any method we like to get a SecureString, convert it to a standard string and then save it to a file. Here is an example of each:

Exporting SecureString from Plain text

"P@ssword1" | `
ConvertTo-SecureString -AsPlainText -Force | `
ConvertFrom-SecureString | `
Out-File "C:\Temp 2\Password.txt"

Exporting SecureString from Get-Credential

(Get-Credential).Password | `
ConvertFrom-SecureString | `
Out-File "C:\Temp 2\Password.txt"

Exporting SecureString from Read-Host

Read-Host "Enter Password" -AsSecureString |  `
ConvertFrom-SecureString | `
Out-File "C:\Temp 2\Password.txt"

Anyone of these examples should provide you with a Password.txt file that has an encrypted standard string the represents the password.

When you need to use this encrypted password, you simply reverse the process by importing the data from your file and use ConvertTo-SecureString. If all you need is a SecureString, you can stop there. You could even take it a step further and create a PSCredential object.

Creating SecureString object

$pass = Get-Content "C:\Temp 2\Password.txt" | ConvertTo-SecureString

Creating PSCredential object

$User = "MyUserName"
$File = "C:\Temp 2\Password.txt"
$MyCredential=New-Object `
-TypeName System.Management.Automation.PSCredential `
-ArgumentList $User,
(Get-Content $File | ConvertTo-SecureString)

Get a certificate with Subject Alternative Names using certreq

If one needs to use certreq to obtain a certificate, but the certificate signing request does not explicitly ask for it, here’s the command to get it anyway:

certreq -f -q -submit -attrib “CertificateTemplate:WebServer\nSAN:dns=<hostname>&dns=<hostname>.mydomain.com&ipaddress=<IP Address>” -config “<Config Name>” <Certificate Request File>.csr <Certificate File>.cer

The key part is in the attrib string following the new line “\n” bit where SAN: is then defined.  In this example, three are defined: the hostname, fully qualified domain name and the IP address.

Active Directory Integrated DNS Wildcard Search

So NSLOOKUP is the typical way one may query DNS.  Ever wanted to just grab the results as objects while using a wildcard filtered search?  If your DNS is Active Directory integrated, then it’s really pretty simple.  After all, each DNS entry is essentially an AD Object.  Why not query AD like we do for so many other things?  Basically, you just need the Distinguished name for the DNS zone and tell Get-ChildItem to look at Active Directory.  For example, if you wanted to find all host records ending in “-DC” in example.com:

Get-ChildItem "AD:DC=example.com,CN=MicrosoftDNS,CN=System,DC=example,DC=com" -Filter "name=*-dc"

By the way, if you get an error stating something similar to this:

Cannot find drive. A drive with the name 'ad' does not exist.

Then you may need to import the Active Directory module.

Import-Module ActiveDirectory

A quick test is to do a change directory to AD.

cd ad:

and the prompt should read “PS AD:\>”

Powershell timestamp for Excel

I needed Powershell to plug in a single value to a .csv file that Excel would naturally convert to a Date and Time.  Here’s the bit to create that value:

# Native Powershell date and time
Get-Date

$excelDate = ((Get-Date).AddDays(1) - (Get-Date "12/31/1899")).Days
$excelTime = ((Get-Date -Format HH)/24)+((Get-Date -Format mm)/1440)+((Get-Date -Format ss)/86400)
$excelTimeStamp = $excelDate + $excelTime

$excelDate
$excelTime
$excelTimeStamp

Get-WinEvent vs. Get-EventLog

So, these two appear to be very similar at first glance.  However, depending on the data one wants to filter in on, one is significantly better than the other.  For me, the bottom line is using Get-Eventlog for filtering the Security Event Log is much faster.  That’s what I needed to know.

An article by Mark Berry was very helpful:

PowerShell: Get-WinEvent vs. Get-EventLog

Conclusions

  1. If you’re writing a PowerShell script to handle events from Vista or Server 2008, avoid the Get-WinEvent –FilterHashtable parameter; use –FilterXML instead.
  2. Even on Vista and beyond, consider using Get-EventLog if you need to filter the Security log for Audit Failures.

Need to parse a remote Event Log for a specific Event ID and text in the description

My situation is that I need to go through all the System events and look for a particular service and account for when it started and stopped.  The one way I am able to identify the specific service from a specific vendor is that they identified their software in the description.  The Event ID for services starting and stopping is 7036.  Using this script, I’m able to get all those vendor specific service stop/start events:

Get-WinEvent -ComputerName <computer> -FilterHashtable @{logname='system'; id=7036} | Where-Object {$_.message -like "*<my text to find>*"}

This may also be helpful:

Get-EventLog -ComputerName <computer> -Log "Security" | where {($_.Message -like '*<search text>*') -and ($_.EntryType -eq 'FailureAudit')}

.

What processes are listening on HTTP/HTTPS related ports?

Working in a vacuum when initially looking at a server is par for course.  My one clue is that the server for a web application of sorts.   However, one does not know what the application is or what software may be serving up HTTP/HTTPS.  Standards are that the server would be serving up on ports 80 and/or 443, respectively.   Many applications will serve up this kind of traffic on variations like 8080 or, essentially, *80 and *443.  I needed a script to quickly see what processes may be listening on those ports.  This helps me gain insight to track down pieces and help the application owner/team investigate further.  Here’s the script:

# Look for listening ports on *80 and *443 with process ID
$Processes = @{}
Get-Process -IncludeUserName | ForEach-Object {
 $Processes[$_.Id] = $_
}

Get-NetTCPConnection | 
 Where-Object { ($_.State -eq "Listen") -and ($_.LocalPort -like '*80' -or $_.LocalPort -like '*443') } |
 Select-Object LocalAddress,
 LocalPort,
 @{Name="PID"; Expression={ $_.OwningProcess }},
 @{Name="ProcessName"; Expression={ $Processes[[int]$_.OwningProcess].ProcessName }}, 
 @{Name="UserName"; Expression={ $Processes[[int]$_.OwningProcess].UserName }} |
 Sort-Object -Property ProcessName, UserName |
 Format-Table -AutoSize

Who initiated the reboot?

This Powershell one liner will check the event log of a remote computer to see what initiated the shutdown or reboot.  If the server just crashed or power was interrupted you can filter on a different Event ID.

Get-EventLog -ComputerName <servername> -LogName System | Where-Object {$_.EventID -eq 1074} | Select-Object -First 1 | FL *