DCSIMG
May 2009 - Posts - Shay Levy

Shay Levy

If you repeat it, PowerShell it!

News


btn_donate_LG

View Shay Levy's profile on LinkedIn Follow Shay Levy at Twitter Shay Levy's Facebook profile Subscribe to my FriendFeed


site statistics




May 2009 - Posts

How to find expired certificates

Windows PowerShell  provides access to X509 certificate stores and digital certificates through the Certificate provider (more on providers). The following example shows how we can get a list of certificates from the CurrentUser Root store. Here’s a list of properties of the first certificate:

PS > $certs = dir cert:\CurrentUser\Root
PS > $certs[0] | Format-List *


PSPath             : Microsoft.PowerShell.Security\Certificate::CurrentUser\Roo
                     t\CDD4EEAE6000AC7F40C3802C171E30148030C072
PSParentPath       : Microsoft.PowerShell.Security\Certificate::CurrentUser\Roo
                     t
PSChildName        : CDD4EEAE6000AC7F40C3802C171E30148030C072
PSDrive            : cert
PSProvider         : Microsoft.PowerShell.Security\Certificate
PSIsContainer      : False
Archived           : False
Extensions         : {System.Security.Cryptography.Oid, System.Security.Cryptog
                     raphy.Oid, System.Security.Cryptography.Oid, System.Securi
                     ty.Cryptography.Oid}
FriendlyName       : Microsoft Root Certificate Authority
IssuerName         : System.Security.Cryptography.X509Certificates.X500Distingu
                     ishedName
NotAfter           : 5/10/2021 2:28:13 AM
NotBefore          : 5/10/2001 2:19:22 AM
HasPrivateKey      : False
PrivateKey         :
PublicKey          : System.Security.Cryptography.X509Certificates.PublicKey
RawData            : {48, 130, 5, 153...}
SerialNumber       : 79AD16A14AA0A5AD4C7358F407132E65
SubjectName        : System.Security.Cryptography.X509Certificates.X500Distingu
                     ishedName
SignatureAlgorithm : System.Security.Cryptography.Oid
Thumbprint         : CDD4EEAE6000AC7F40C3802C171E30148030C072
Version            : 3
Handle             : 76086496
Issuer             : CN=Microsoft Root Certificate Authority, DC=microsoft, DC=
                     com
Subject            : CN=Microsoft Root Certificate Authority, DC=microsoft, DC=
                     com

There is plenty of information but there is one property that I’m missing. I want to know if the certificate has expired. We can write a simple expression to find it. Notice the two yellowed members: NotAfter and NotBefore. These members shows the date range where the cert is valid for use. We can use the NotAfter property to test if the certificate has expired::

PS > $certs[0].NotAfter -lt (Get-Date)
False



If NotAfter is less than the current date and time (True) then the certificate has expired otherwise it is valid (False). With a calculated property we can introduce a new property to display the information for one or all X509 certificates (output shows the first two only):

PS > $certs | select NotAfter,NotBefore,SerialNumber,`
@{Name="Expired";Expression={$_.NotAfter -lt (Get-Date)}} NotAfter NotBefore SerialNumber Expired -------- --------- ------------ ------- 5/10/2021 02:28:13 AM 5/10/2001 02:19:22 AM 79AD16A14AA0A5AD4C7358F407132E65 False 8/24/2020 02:59:59 AM 8/24/2005 03:00:00 AM 3B67989F8A1BE07568F2ECCA05DFA743 False (...)

To make the new ‘Expired’ property show up every time we list certificates we can extend the certificate type by using a custom types file and load it with the Update-TypeData cmdlet. We need to have three key information for the type file:

1. The Type name of the certificate object.
2. The name of the new property we want to extend.
3. The property expression.

The cert type can be found with Get-member:

PS > $certs[0] | Get-Member

   TypeName: System.Security.Cryptography.X509Certificates.X509Certificate2

Name    MemberType     Definition
----    ----------     ----------
Equals  Method         bool Equals(System.Object obj)
(...)

Save the following xml in a file with ps1xml extension (i.e certs.types.ps1xml):

<?xml version="1.0" encoding="utf-8"?>
<Types>
    <Type>
        <Name>System.Security.Cryptography.X509Certificates.X509Certificate2</Name>
        <Members>
            <ScriptProperty>
                <Name>Expired</Name>
                <GetScriptBlock>$this.NotAfter -lt (Get-Date)</GetScriptBlock>
            </ScriptProperty>
        </Members>   
    </Type>
</Types>

PS > Update-TypeData -PrependPath certs.Types.ps1xml
PS > dir cert:\CurrentUser\Root | select NotAfter,NotBefore,SerialNumber,Expired           

NotAfter               NotBefore              SerialNumber                       Expired
--------               ---------              ------------                       -------
5/10/2021 02:28:13 AM  5/10/2001 02:19:22 AM  79AD16A14AA0A5AD4C7358F407132E65     False
8/24/2020 02:59:59 AM  8/24/2005 03:00:00 AM  3B67989F8A1BE07568F2ECCA05DFA743     False
(...)

Last thing to do is to include the Update-TypeData command in your profile so each time you load PowerShell the certificate type will be extended with the new property.

All About the 2009 Summer Scripting Games

Planning to take part in the upcoming Scripting Games? Get all the answers to your questions on the Scripting Guys blog.

Get-Scripting Podcast interview

GetScripting

Jonathan Medd and Alan Renouf (aka Virtu-Al) invited me for an interview for their Get-Scripting podcast Episode 10.

You can read all the details and download the recording HERE or listen to the streaming version directly from PowerShell Toolbar.

Jonathan & Alan, thanks for inviting me. I had a great time chatting with you guys!

2009 Summer Scripting Games

scripto_torchrunner

Mark your calendars! The 2009 Summer Scripting Games will take place on June 15–26, 2009 and will be hosted by PowerShellCommunity.org and PoshCode.org. The Scripting Games are a chance for IT pros to practice and test their scripting skills during 10 events, using either Microsoft Windows PowerShell or Microsoft VBScript. The Scripting Games begin as a live event with contestants submitting entries in a beginning or advanced division that are judged and scored by the community.

"We are looking forward to the Scripting Games and being part of the community in helping 1,000 or more script writers in showcasing their craft," said Hal Rottenberg, director of PowerShellCommunity.org. "Sponsors of PowerShellCommunity.org such as Idera, Quest Software, Inc., Compellent and SAPIEN Technologies, Inc., help us provide this venue for Windows PowerShell users to collaborate and communicate."

To enter the Scripting Games, visit http://www.microsoft.com/technet/scriptcenter/funzone/games/default.mspx on June 15. To get all the latest information about the Scripting Games, follow the Scripting Guys, Ed Wilson and Craig Liebendorfer, on Twitter. Hope to see you all there, it’s going to be FUN.

Upcoming Webcast: Exchange 2010 Management Tools (Level 300)

Exchange14

Exchange 2010 includes new capabilities that make the operation of your Exchange environment more efficient.  Learn how we’ve made the Exchange Management Console more powerful, extended the reach of PowerShell, and made it easier to delegate management tasks. You can register HERE.    

Presenter: Evan Dodds, US-Exchange Shared PM, Microsoft Corporation.
Start Date: Monday, June 08, 2009 1:00 PM Pacific Time (US & Canada)

Running PowerShell 1.0 and 2.0 on the same machine

Windows XP Mode (XPM) for Windows 7 makes it easy to install and run many of your Windows XP productivity applications directly from a Windows 7 based PC. It utilizes virtualization technology such as Windows Virtual PC to provide a Virtual Windows XP environment for Windows 7. Windows XP Mode provides a 32-bit Windows XP Professional Service Pack 3 (SP3) environment pre-loaded on a virtual hard disk.

In this post I’ll demonstrate how to install, publish and launch PowerShell 1.0 side by side with PowerShell 2.0 which is already a part of Windows 7. First, you need to download Windows Virtual PC Beta and Windows XP Mode. Lets’ start.

Install Windows6.1-KB958559-x64.msu and reboot if asked to. Next run VirtualWindowsXP.msi

 

It is recommended to save the password you choose. That way you won’t have to enter the user credentials each time you launch XPM.

At this point XPM is loading and initializing its components

 

XPM performs auto logon (if you choose to save the user credentials). When you open My Computer you’ll see your Windows 7 local drives as mapped drives. That way you can copy/run files from Windows 7 into XPM. You cannot drag & drop files into XPM, maybe future releases will have that feature. Make a folder on one of your Windows 7 local drives and put there a copy of .NET 2.0 and Windows PowerShell 1.0. Install .NET and then install PowerShell 1.0.

Now for a little gotcha. Someone at Microsoft decided to block PowerShell and PowerShell ISE (and a bunch of other applications), XPM won’t publish their shortcuts to Windows 7 start menu. You’ll need to delete the ‘PowerShell’ values so XPM can publish their shortcuts.

I want to thank MVP Charlie Russel for sharing this tip with me!

 

Launch PowerShell 1.0 and create a profile. I had some issues when I tried to launch PowerShell 1.0 with no profile, for some reason it ran my Windows 7 profile.

EDIT: You can force XPM PowerShell to load your v1 profile if you disable the “Drives” sharing in ‘Integration Features’ (Tools | Settings…)

ics

 

Now close the VM by pressing the X button (you may need to reboot the VM, press CTRL+ALT+DEL at the top menu and then press the Shutdown button).

Take a look at Windows 7 start menu, XPM will (hopefully) publish PowerShell shortcuts :-), you should see something like the following:

As you can see all of PowerShell’s shortcuts were published except for PowerShell itself. In this case launch XPM again and copy the PowerShell shortcut under ALLUSERS profile.

Close the VM (you may have to reboot it again) and check if the shortcut was published.

OK, now click the ‘Windows PowerShell (Virtual Windows XP 1)’ shortcut, you’ll probably get this dialog:

Click ‘Open Virtual Application’, this will launch PowerShell 1.0 in seamless mode, here’s a screenshot of my desktop showing both versions of PowerShell running on the same machine:

Isn’t that great!

PowerShell Toolbar (updated)


Last year I blogged about the PowerShell Toolbar. Since than the toolbar was downloaded more than 850 times. I would like to thanks all the people who used it and still are, your comments have helped me a lot in improving it. Again, if you feel I missed something or someone, please leave a comment or send me an email through the contact section of this blog or through the toolbar itself.

Here are the latest improvements and changes. You can download the toolbar HERE.

 Search  
PSSearch

When you click the little down arrow you’ll find a new search option ‘PowerShell Forums Search’. Using this option performs a search in several PowerShell known forums, such as:

  • PowerShellCommunity.org
  • PowerGUI.org 
  • PowerShell.com
  • StackOverflow.com
  • PoshCode.org
   

Blogs

 
PSBlogs The Blogs section has been updated and now includes a submenu for Windows PowerShell MVP blogs as well as others like MSFTs and PowerShell bloggers.
   
Radio  
PSPodcasts

In the Radio section you’ll be able to listen to Jonathan and Alan’s Get-Scripting podcasts

   
Resources  
PSRes

New menus were added, like: PowerShell training, Script Repositories and more.

   
Twitter  

PSTwitter

The Twitter gadget is new to the toolbar. You can read the last 15 PowerShell tweets even if you don’t have Twitter account. The widget is floating so you can position it anywhere inside the browser window, content should refresh every 1 minute.

And if you are using Twitter then you can get update notifications by following @PSToolbar.

Show or hide your desktop icons with PowerShell

I was reading through James' blog post and remembered that I wrote a script some time ago to show or hide desktop icons. The script requires PowerShell 2.0 and shows how you can access WIN32 APIs.


#requires -Version 2.0

$signature = @"
[DllImport("user32.dll")] 
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 
[DllImport("user32.dll")] 
public static extern bool ShowWindow(IntPtr hWnd,int nCmdShow);
"@

$icons = Add-Type -MemberDefinition $signature -Name Win32Window `
         -Namespace ScriptFanatic.WinAPI -passThru

$hWnd=$icons::FindWindow("Progman","Program Manager")

function Hide-DesktopIcons{$null = $icons::ShowWindow($hWnd,0) }
function Show-DesktopIcons{$null = $icons::ShowWindow($hWnd,5) }



How to use it

Save the code in script file, say 'Set-DesktopIcons.ps1' and load it via Import-Module cmdlet (i.e Import-Module .\Set-DesktopIcons.ps1). By default, Import-Module export all module members (functions/aliases/variables etc) defined in the module into your session. To specify which members to export use the Export-ModuleMember cmdlet. Now that you've loaded the module you can call the exported functions just like any other cmdlet. PowerShell will auto complete the functions name as well; just type: 'Hide-' or ‘Show-' and press the TAB key.

There is a great post by Lee holmes to guide you through the process of invoking WIN32 APIs in PowerShell. It helped me a lot with the script.

How to send Twitter direct messages from PowerShell

This function sends a direct message (DM) from your Twitter account to another Twitter user, notice that you can only send a direct message to a person who follows you.


function Send-DirectTweet($Recipient,$Message,$UserName,$Password){
  
$url="http://twitter.com/direct_messages/new.xml?user=$Recipient&text=$Message"
  
$request = [System.Net.WebRequest]::Create($url)
  
$request.credentials= New-Object System.Net.NetworkCredential($UserName,$Password)
  
$request.method= "POST"
  
$request.contentType = "application/x-www-form-urlencoded"
  
$request.GetResponse().statusCode # return the status code of the request
}

# sample usage
Send-DirectTweet -Recipient twitterUser -Message Hi -UserName yourUserName -Password yourPassword