Matt Penny

Subscribe to Matt Penny feed Matt Penny
Updated: 16 hours 47 min ago

Importing windows scheduled tasks into a Powershell object before 5.0

Mon, 2016-07-18 07:43

You don’t need this on Powershell 5.0 and upwards because there’s a built-in cmdlet, but for previous versions:


convertfrom-csv $(schtasks /Query /S server1 /TN "run somesstuff" /V /FO CSV)

HostName : server1
TaskName : \run somesstuff
Next Run Time : N/A
Status : Ready
Logon Mode : Interactive only
Last Run Time : 13/07/2016 10:05:43
Last Result : 0
Author : matt
Task To Run : C:\powershell\Modules\somesstuff-PCs\run-somesstuff.bat
Start In : N/A
Comment : Scheduled job which does some stuff
Scheduled Task State :
Idle Time :
Power Management :
Run As User :
Delete Task If Not Rescheduled :
Stop Task If Runs X Hours and X Mins :
Schedule :
Schedule Type :
Start Time :
Start Date :
End Date :
Days :
Months :
Repeat: Every :
Repeat: Until: Time :
Repeat: Until: Duration :
Repeat: Stop If Still Running :

HostName : More detail at http://ourwebsite
TaskName : Enabled
Next Run Time : Disabled
Status : Stop On Battery Mode, No Start On Batteries
Logon Mode : matt
Last Run Time : Enabled
Last Result : 72:00:00
Author : Scheduling data is not available in this format.
Task To Run : One Time Only
Start In : 10:20:21
Comment : 25/05/2016
Scheduled Task State : N/A
Idle Time : N/A
Power Management : N/A
Run As User : Disabled
Delete Task If Not Rescheduled : Disabled
Stop Task If Runs X Hours and X Mins : Disabled
Schedule : Disabled
Schedule Type :
Start Time :
Start Date :
End Date :
Days :
Months :
Repeat: Every :
Repeat: Until: Time :
Repeat: Until: Duration :
Repeat: Stop If Still Running :


This is outputting from schtasks in csv format, then importing that into a PowerShell object.


Categories: DBA Blogs

sketchnote of confluence keyboard shortcuts

Mon, 2016-07-18 03:03

Confluence keyboard shortcuts sketchnote


Categories: DBA Blogs

Pester: Cannot bind argument to parameter ‘Actual’ because it is an empty string.

Tue, 2016-06-21 03:23

I’m just getting started with Pester and I got this error

   Cannot bind argument to parameter 'Actual' because it is an empty string.
   at line: 18 in C:\Program Files\WindowsPowerShell\Modules\pester\3.3.5\Functions\Assertions\Be.ps1

The code I’m testing is very simple – it just separates a ‘Property Name’ and a ‘Property Value’.

So, when it’s working it does this:

get-HugoNameAndValue -FrontMatterLine "Weighting: 103"
DEBUG: 09:15:37.6806 Start: get-HugoNameAndValue
DEBUG: - FrontMatterLine=Weighting: 103
DEBUG: - get-HugoNameAndValue.ps1: line 5
DEBUG: $PositionOfFirstColon: 9
DEBUG: $PropertyName : {Weighting}
DEBUG: $PropertyValue : { 103}
DEBUG: $PropertyValue : {103}

PropertyName PropertyValue
------------ -------------
Weighting    103          

When I ran it from Pester I got this

GetHugoNameAndValue 06/21/2016 08:45:19 $ invoke-pester
Describing get-HugoNameAndValue
DEBUG: 08:45:56.3377 Start: get-HugoNameAndValue
DEBUG: - FrontMatterLine=Weighting: 103
DEBUG: - get-HugoNameAndValue.ps1: line 5
DEBUG: $PositionOfFirstColon: 9
DEBUG: $PropertyName : {Weighting}
DEBUG: $PropertyValue : { 103}
DEBUG: $PropertyValue : {103}
 [-] returns name and value 189ms
   Cannot bind argument to parameter 'Actual' because it is an empty string.
   at line: 18 in C:\Program Files\WindowsPowerShell\Modules\pester\3.3.5\Functions\Assertions\Be.ps1
Tests completed in 189ms
Passed: 0 Failed: 1 Skipped: 0 Pending: 0

My Pester code was:

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
. "$here\$sut"

Describe "get-HugoNameAndValue" {
    It "returns name and value" {
        $Hugo = get-HugoNameAndValue -FrontMatterLine "Weighting: 103"
        $value = $Hugo.Value
        $value | Should Be '103'
    }
}

The problem here was simply that I’d got the name of the Property wrong. It was ‘PropertyName’ not just ‘Name’

So I changed the Pester

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
. "$here\$sut"

Describe "get-HugoNameAndValue" {
    It "returns name and value" {
        $Hugo = get-HugoNameAndValue -FrontMatterLine "Weighting: 103"
        $value = $Hugo.PropertyValue
        $value | Should Be '103'
    }
}

….and then it worked

invoke-pester
Describing get-HugoNameAndValue
DEBUG: 09:22:21.2291 Start: get-HugoNameAndValue
DEBUG: - FrontMatterLine=Weighting: 103
DEBUG: - get-HugoNameAndValue.ps1: line 5
DEBUG: $PositionOfFirstColon: 9
DEBUG: $PropertyName : {Weighting}
DEBUG: $PropertyValue : { 103}
DEBUG: $PropertyValue : {103}
 [+] returns name and value 99ms
Tests completed in 99ms
Passed: 1 Failed: 0 Skipped: 0 Pending: 0

Categories: DBA Blogs

sketchnote of Ed Wilson’s talk on ‘Operations Management Suite’

Fri, 2016-05-27 11:17

Wilson, Ed - Microsoft Operations Management Suite

The OMS blog is: https://blogs.technet.microsoft.com/msoms/
The Scripting Guy blog is: https://blogs.technet.microsoft.com/heyscriptingguy/
Ed Wilson is on twitter here: https://twitter.com/ScriptingGuys
The London Powershell Users Group tweets here: https://twitter.com/lonpsug
The UK Powershell Users Group is http://www.get-psuguk.org/

Keywords: OMS, Powershell


Categories: DBA Blogs

get a list of powershell date format outputs

Wed, 2016-02-10 07:01

I want to create a list of Powershell date formats and their outputs, for a quick reference doc.

I’ve collected a list of formats from the Powershell help text and other locations and put them in a big text file which looks like this:

get-date -Uformat %A   # Day of the week - full name 
get-date -Uformat %u   # Day of the week - number (Monday = 1)
get-date -Uformat %d   # Day of the month - 2 digits 
get-date -Uformat %e   # Day of the month - digit preceded by a space ( 5)
get-date -Uformat %j   # Day of the year 
get-date -Uformat %p   # AM or PM
get-date -Uformat %r   # Time in 12-hour format
get-date -Uformat %R   # Time in 24-hour format - no seconds
get-date -Uformat %T   # Time in 24 hour format

I’m going to order this in what I consider to be order of usefullness (to me), because I’m going to plug it into an about_dateformats help page in my Powershell-help-powered repository of notes and tips.

To generate a list with the command, output and comment, I did this:

$Dates = foreach ($L in $(Select-String -notmatch "^$" formats.txt)) 
{
  [string]$Line = $L.Line
  $Command = $Line.split('#')[0]
  $Comment = $Line.split('#')[1]

  $scriptBlock = $executioncontext.InvokeCommand.NewScriptBlock($Line)

  $Output = invoke-command $ScriptBlock

  # write-output "$Command $Output # $Comment"
  new-object PSObject -Property @{
     Command = $Command
     Output =  $Output
     Comment = $Comment
  }

} 

$Dates | ft -a

The output looks like this:

<br />Output                            Command                                             Comment                                                           
------                            -------                                             -------                                                           
10                                Get-Date -UFormat %d                                                                                                  
Wed Feb 10 12:44:52 2016          get-date -UFormat %c                                 Date and time - abbreviated (Fri Jun 16 10:31:27 2006)           
02/10/16                          get-date -UFormat %D                                 Date in mm/dd/yy format (06/14/06)                               
02/10/16                          get-date -UFormat %x                                 Date in standard format for locale (09/12/07 for English-US)     
20                                get-date -Uformat %C                                 Century (20 for 2006)                                            
2016                              get-date -Uformat %Y                                 Year in 4-digit format (2006)                                    
16                                get-date -Uformat %y                                 Year in 2-digit format (06)                                      
Feb                               get-date -Uformat %b                                 Month name - abbreviated (Jan)                                   
February                          get-date -Uformat %B                                 Month name - full (January)                                      
02                                get-date -Uformat %m                                 Month number (06)                                                
5                                 get-date -Uformat %W                                 Week of the year (00-52)                                         
6                                 get-date -Uformat %V                                 Week of the year (01-53)                                         
Wed                               get-date -Uformat %a                                 Day of the week - abbreviated name (Mon)                         
Wednesday                         get-date -Uformat %A                                 Day of the week - full name (Monday)                             
3                                 get-date -Uformat %u                                 Day of the week - number (Monday = 1)                            
10                                get-date -Uformat %d                                 Day of the month - 2 digits (05)                                 
10                                get-date -Uformat %e                                 Day of the month - digit preceded by a space ( 5)                
41                                get-date -Uformat %j                                 Day of the year - (1-366)                                        
PM                                get-date -Uformat %p                                 AM or PM                                                         
12:44:52 PM                       get-date -Uformat %r                                 Time in 12-hour format (09:15:36 AM)                             
12:44                             get-date -Uformat %R                                 Time in 24-hour format - no seconds (17:45)                      
12:44:52                          get-date -Uformat %T                                 Time in 24 hour format (17:45:52)                                
+00                               get-date -Uformat %Z                                 Time zone offset from Universal Time Coordinate (UTC) (-07)      
12                                get-date -Uformat %H                                 Hour in 24-hour format (17)                                      
12                                get-date -Uformat %I                                 Hour in 12 hour format (05)                                      
44                                get-date -Uformat %M                                 Minutes (35)                                                     
52                                get-date -Uformat %S                                 Seconds (05)                                                     
1455108292.3719                   get-date -Uformat %s                                 Seconds elapsed since January 1, 1970 00:00:00 (1150451174.95705)
10/02/2016 12:44:52               Get-Date -DisplayHint Date                                                                                            
10/02/2016 12:44                  Get-Date -Format g                                                                                                    
2016 / 02 / 10 / Wednesday / +00  Get-Date -UFormat "%Y / %m / %d / %A / %Z"                                                                            
366                               (Get-Date -Year 2000 -Month 12 -Day 31).DayOfYear                                                                     
False                             $(get-date).IsDaylightSavingTime()                                                                                    
10/02/2016 12:44:52               $(get-date).ToUniversalTime()                                                                                         
10/02/2016 12:44:52               (Get-Date).ToString()                                                                                                 
2016-02-10T12:44:52.3749035+00:00 Get-Date -Format o                                                                                                    
2016-02-10T12.44.52.3759036+00.00 Get-Date -Format o | foreach {$_ -replace ":", "."}                           

Categories: DBA Blogs

fix for ‘Cannot convert value “System.Xml.XmlElement” to type “System.Xml.XmlDocument”‘

Mon, 2016-02-08 13:51
Quick fix

Change:

Param( [xml]$WordpressPostAsXml

to

Param( [system.xml.xmlelement]$WordpressPostAsXml
Slightly More Detail

I’m in the process of coding a Powershell module to convert an xml file containing the content of my old WordPress site to a set of Markdown files for Hugo.

I got the error:

get-wpHugoFileName : Cannot process argument transformation on parameter 'WordpressPostAsXml'. Cannot convert value "System.Xml.XmlElement" to 
type "System.Xml.XmlDocument". Error: "The specified node cannot be inserted as the valid child of this node, because the specified node is the 
wrong type."
At C:\users\matt\Documents\WindowsPowershell\functions\function-get-WordpressContent.ps1:43 char:63
+ ... goFileName = get-wpHugoFileName -WordPressPost $WordPressPost -Conten ...
+                                                    ~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [get-wpHugoFileName], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,get-wpHugoFileName

In summary, there are three relevant functions

  • convert-wpPostToHugo – receieves an exported WordPress site in Xml format. Calls get-wpMatchingWordpressPosts to extract the specified bits, then get-wpHugoFileName for each post
  • get-wpMatchingWordpressPosts – extracts the xml nodes for posts which match a specified string
  • get-wpHugoFileName – called for each xml ‘node’. Returns a file name for the markdown content

convert-wpPostToHugo:

function  convert-wpPostToHugo{ 

  [CmdletBinding()]
  Param( [xml][Alias ("xml")]$WordpressXML = "$wp_xml",
         [string][Alias ("string")]$PostString = "ramone" ,
         [string][Alias ("f")]$ContentFolder = "c:\temp"
) 
  write-debug "$(get-date -format 'hh:mm:ss.ffff') Function beg: $([string]$MyInvocation.Line) "

  $MatchingWordPressPosts = get-wpMatchingWordpressPosts -WordPressXml $WordPressXML -PostString $Poststring

  foreach ($WordPressPost in $MatchingWordPressPosts)
  {    
    [String]$HugoFileName = get-wpHugoFileName -WordPressPost $WordPressPost -ContentFolder $contentFolder
    write-verbose "`$HugoFileName: $HugoFileName"

get-wpMatchingWordpressPosts:

function get-wpMatchingWordpressPosts { 
  [CmdletBinding()]
  Param( [xml][Alias ("xml")]$WordpressXML = "$wp_xml",
         [string][Alias ("string")]$PostString = "ramone"         ) 

  write-debug "$(get-date -format 'hh:mm:ss.ffff') Function beg: $([string]$MyInvocation.Line) "

  $Nodes = select-xml -xml $WordpressXML -xpath "//channel/item" | select -expandproperty node | where-object title -like "*$PostString*"


  return $nodes

get-wpHugoFileName:

function get-wpHugoFileName { 

  [CmdletBinding()]
  Param( [xml][Alias ("x")]$WordpressPostAsXml,
         [string][Alias ("f")]$ContentFolder = "c:\temp" )

  write-debug "$(get-date -format 'hh:mm:ss.ffff') Function beg: $([string]$MyInvocation.Line) "

The fix was to change the definition of the $WordPressPost from xml to [system.xml.xmlelement]:
get-wpHugoFileName:

function get-wpHugoFileName { 

  [CmdletBinding()]
  Param( [system.xml.xmlelement][Alias ("x")]$WordpressPostAsXml,
         [string][Alias ("f")]$ContentFolder = "c:\temp" )

  write-debug "$(get-date -format 'hh:mm:ss.ffff') Function beg: $([string]$MyInvocation.Line) "

This makes sense….the variable returned from get-wpMatchingWordpressPosts is no longer a valid XML document – it is just elements of an XML document.


Categories: DBA Blogs

how to install powershell active directory module

Tue, 2016-02-02 13:23

install: en_windows_7_professional_with_sp1_vl_build_x64_dvd_u_677791.iso

dism /online /enable-feature /featurename:RemoteServerAdministrationTools-Roles-AD
dism /online /enable-feature /featurename:RemoteServerAdministrationTools-Roles-AD-Powershell

Categories: DBA Blogs

using powershell’s help system to stash your tips and tricks in ‘about_’ topics

Sat, 2016-01-30 15:55

There are a bunch of bits of syntax which I struggle to remember.

I’m not always online when I’m using my laptop, but I always have a Powershell window open.

This is a possibly not-best-practice way of using Powershell’s wonderful help system to store bits of reference material.

The problem

I’m moving a WordPress blog to Hugo, which uses Markdown, but I’m struggling to remember the Markdown syntax. It’s not difficult, but I’m getting old and I get confused with Twiki syntax.

In any case this ‘technique’ could be used for anything.

I could equally well just store the content in a big text file, and select-string it….but this is more fun :)

The content

In this instance I only need a few lines as an aide-memoire:

    ## The second largest heading (an <h2> tag)
    > Blockquotes
    *italic* or _italic_
    **bold** or __bold__
    * Item (no spaces before the *) or
    - Item (no spaces before the -)
    1. Item 1
      1. Furthermore, ...
    2. Item 2
    `monospace` (backticks)
    ```` begin/end code block
    [A link!](http://mattypenny.net).
create a module

The module path is given by:

$env:PSModulePath

Mine is:

C:\Users\matty\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules\;C:\Program Files (x86)\Microsoft SQL Server\110\Tools\PowerShell\Modules\

Pick one of this folders to create your module in and do this:

mkdir C:\Users\matty\Documents\WindowsPowerShell\Modules\QuickReference

Then create a dummy Powershell module file in the folder

notepad C:\Users\matty\Documents\WindowsPowerShell\Modules\QuickReference\QuickReference.psm1

The content of the module file is throwaway:

function dummy {write-output "This is a dummy"}
create the help file(s)

Create a language-specific folder for the help files

mkdir C:\Users\matty\Documents\WindowsPowerShell\Modules\QuickReference\en-US\

Edit a file called about_.help.txt

notepad C:\Users\mpenny2\Documents\WindowsPowerShell\Modules\QuickReference\en-US\about_Markdown.help.txt

My content looked like this:

TOPIC
    about_Markdown

SHORT DESCRIPTION
    Syntax for Markdown 

LONG DESCRIPTION

    ## The second largest heading (an <h2> tag)
    > Blockquotes
    *italic* or _italic_
    **bold** or __bold__
    * Item (no spaces before the *) or
    - Item (no spaces before the -)
    1. Item 1
      1. Furthermore, ...
    2. Item 2
    `monospace` (backticks)
    ```` begin/end code block
    [A link!](http://mattypenny.net).
Use the help

I can now do this (I’ll import the module in my $profile):

PS C:\Windows> import-module QuickReference

Then I can access my Markdown help from within Powershelll

PS C:\Windows> help Markdown
TOPIC
    about_Markdown

SHORT DESCRIPTION
    Syntax for Markdown 

LONG DESCRIPTION

    ## The second largest heading (an <h2> tag)
    > Blockquotes
    *italic* or _italic_
    **bold** or __bold__
    * Item (no spaces before the *) or
    - Item (no spaces before the -)
    1. Item 1
      1. Furthermore, ...
    2. Item 2
    `monospace` (backticks)
    ```` begin/end code block
    [A link!](http://mattypenny.net).

Categories: DBA Blogs