Wednesday, November 27, 2013

Everyday Powershell - Part 10 - Powershell to check if certificates are going to expire

This is the next part in an ongoing series about Powershell. You may have heard about how awesome Powershell is but have struggled to find ways to make it useful in your day to day work. That's what this series is going to address. It'll provide scripts and knowledge to address practical everyday problems

This weeks script was a request from a reader. He wanted a reminder of when certificates were going to expire on his server. Having felt the stress of running through Extended Validation for production certificates with only hours to spare before expiry, the need for such a script was obvious.

$days = 60
$certs = $null
$certs = Get-ChildItem -Path cert: -Recurse -ExpiringInDays $days | select Subject, thumbprint, notafter
if ($certs -ne $null)
{
    [string]$body = $certs | convertto-html -Body $_
    Send-MailMessage -To someone@someserver.com -From someone@someserver.com -Subject "Certificates Expiring in $days days" -SmtpServer somemailserver -BodyAsHtml $body
}

The great thing is it's bloody easy with Powershell 4. If you are not up to date you should be it's easy!

Just schedule this to run at a regular schedule if only there was some kind of guide to do that in powershell.

Requests are fun! If you have a need for a script to do anything post a comment or send me tweet @benhaslett I'd be happy to give it a crack! Or at the very least I can Google around and see if someone has done something similar!

Wednesday, November 20, 2013

Everyday Powershell - Part 9 - Scheduling Powershell in Powershell

This is the next part in an ongoing series about Powershell. You may have heard about how awesome Powershell is but have struggled to find ways to make it useful in your day to day work. That's what this series is going to address. It'll provide scripts and knowledge to address practical everyday problems

Todd Klindt brings us this awesome bit of trickery. You may remember from Part 1 of this series we went over how to schedule a script using the GUI... But what kind of scripter uses the GUI for anything!? Well Todd's post over on the weekend scripter gives us everything we need to ditch the GUI for scheduling tasks.

So this script can be used to schedule any other scripts. We've used the one from Part 2 saved it in C:\powershell with the filename say-bofhexcuse.ps1

#http://blogs.technet.com/b/heyscriptingguy/archive/2013/11/09/weekend-scripter-use-powershell-to-back-up-sharepoint-installation.aspx?utm_source=twitterfeed&utm_medium=twitter
$password = ConvertTo-SecureString 'Wouldn'tyouliketoknow?' -AsPlainText -Force
$account = New-Object system.management.automation.pscredential 'SomeUser', $password
$opt = New-ScheduledJobOption -RunElevated
Register-ScheduledJob -Name BOFH-SPEAKS -FilePath C:\Powershell\say-BOFHexcuse.ps1 -Credential $account -ScheduledJobOption $opt

$t = New-JobTrigger -atlogon

Get-ScheduledJob -Name BOFH-SPEAKS | Set-ScheduledJob -Trigger $t

Once we've got the job setup we can test it with;
Start-Job -DefinitionName BOFH-SPEAKS

The New-JobTrigger bit will accept all kinds of triggers, you'll need to check the doco for all the tricky parts. We're just running this one at logon. So when you login of a morning you'll get a new excuse!

Monday, November 18, 2013

They're having a laugh right?

So I'm doing some doco on our Active Directory Forest Restore procedure and found this gem in the documentation... The excess of procedural detail here made me giggle.


Do we really need such detailed instructions to add 100,000 to another number?

Here's the original article if you don't believe it;
http://technet.microsoft.com/en-us/library/8e3e4377-ef54-4a70-9215-a5d2ba4d0eb9(v=ws.10)#RaiseRIDPool

I mean I get that this is probably because someone made a bad mistake with this process back in the day and Microsoft are covering themselves.

BUT I'd PREFER to believe that is some passive aggressive technical writer having a dig at relative intellect of the average Active Directory admin.

Wednesday, November 13, 2013

Everyday Powershell - Part 8 - Powershell Slideshow

This is the next part in an ongoing series about Powershell. You may have heard about how awesome Powershell is but have struggled to find ways to make it useful in your day to day work. That's what this series is going to address. It'll provide scripts and knowledge to address practical everyday problems

First let me congratulate you finding this article! Especially if you came via Google. Finding a blog post on "Powershell Slideshows" among all the "Powerpoint" slideshows would have been an interesting challenge!

Let's say you wanted a PC to boot up and show a slideshow of images in a given folder. Do you think that you'd need some third party software? Could windows photo viewer do it? A colleague of mine was about to create a video in Windows Movie Maker before I asked...

"Why don't we try POWERSHELL?"

$folder = "C:\Users\someuser\Documents\Pictures\"
$wait = 1

[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$form = new-object Windows.Forms.Form
$form.Text = "Image Viewer"
$form.WindowState= "Maximized"
$form.controlbox = $false
$form.formborderstyle = "0"
$form.BackColor = [System.Drawing.Color]::black

$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.dock = "fill"
$pictureBox.sizemode = 4
$form.controls.add($pictureBox)
$form.Add_Shown( { $form.Activate()} )
$form.Show()

do
{
    $files = (get-childitem $folder | where { ! $_.PSIsContainer})
    foreach ($file in $files)
    {
        $pictureBox.Image = [System.Drawing.Image]::Fromfile($file.fullname)
        Start-Sleep -Seconds $wait
        $form.bringtofront()
    }
}
While ($running -ne 1)

Most of this was pinched from here;

Our contribution is the fact it's Fullscreen and the Do While loop. Those clever observers among us will notice the $running will never equal 1 so that do loop is infinite. Which suits our purpose just fine.

What started as a way to settle an argument with a colleague (about the usefulness of powershell in media rich environments) became a great way to demo the windows.forms objects!

Beware though it is a bit of mess from a UI perspective. You can't quit the form once it's shown, you can alt tab and kill it from task manager when you need to close it. It suits what we need because it's just for a PC that boots up and runs a slide show, then shuts down at night. The users won't have to ever touch this PC. This is not something I'd give to end users to interact with. But it's fine for our purposes.

Wednesday, November 6, 2013

Everyday Powershell - Part 7 - Powershell to Upgrade Powershell 4

This is the next part in an ongoing series about Powershell. You may have heard about how awesome Powershell is but have struggled to find ways to make it useful in your day to day work. That's what this series is going to address. It'll provide scripts and knowledge to address practical everyday problems!

This is a script you can run that'll upgrade you to the newest version of the Windows Management Framework (version 4). What's so good about WMF4? Why Powershell 4 is in it!

#http://download.microsoft.com/download/3/D/6/3D61D262-8549-4769-A660-230B67E15B25/Windows8-RT-KB2799888-x64.msu

if ($PSVersionTable.psversion.Major -ge 4)
{
    write-host "Powershell 4 Installed already you don't need this"
    Exit-PSSession
}

$powershellpath = "C:\powershell"

function download-file
{
    param ([string]$path, [string]$local)
    $client = new-object system.net.WebClient
    $client.Headers.Add("user-agent", "PowerShell")
    $client.downloadfile($path, $local)
}


if (!(test-path $powershellpath))
{
    New-Item -ItemType directory -Path $powershellpath
}

if (($PSVersionTable.CLRVersion.Major) -lt 4)
{
    $DownloadUrl = "http://download.microsoft.com/download/B/A/4/BA4A7E71-2906-4B2D-A0E1-80CF16844F5F/dotNetFx45_Full_setup.exe"
    $FileName = $DownLoadUrl.Split('/')[-1]
    download-file $downloadurl "$powershellpath\$filename"
    ."$powershellpath\$filename"
}

#You may need to reboot after the .NET 4.5 install if so just run the script again.

if ([System.IntPtr]::Size -eq 4)
{
    $DownloadUrl = "http://download.microsoft.com/download/3/D/6/3D61D262-8549-4769-A660-230B67E15B25/Windows6.1-KB2819745-x86-MultiPkg.msu"
}
Else
{
    $DownloadUrl = "http://download.microsoft.com/download/3/D/6/3D61D262-8549-4769-A660-230B67E15B25/Windows6.1-KB2819745-x64-MultiPkg.msu"
}

$FileName = $DownLoadUrl.Split('/')[-1]
download-file $downloadurl "$powershellpath\$filename"

."$powershellpath\$filename"

You can use this script to save you typing ".net 4.5 framework" and "windows management framework 4" into Google. It's got the Microsoft download URLs hardcoded, and we use our tricky download-file function from weeks ago. Which is the great thing about getting into scripting, you really only have to solve a particular problem once! When the solution is in your script repository you can clone your own work!

The bulk of this script is just checking what .net and powershell versions are installed continuing or breaking depending on that. This should be familiar territory if you've been following along for the past 6 weeks.

We do check the Environment and check if we're running a 64bit version of windows then download the correct WMF file for your OS. That's a bit tricky.

We've also included the WMF for windows 8 so if you've got it installed you can copy and paste that into the $downloadurl (while you wear a potplant for a hat you mad windows 8 bugger you).