{"id":3982,"date":"2014-08-29T14:47:58","date_gmt":"2014-08-29T18:47:58","guid":{"rendered":"http:\/\/jdhitsolutions.com\/blog\/?p=3982"},"modified":"2014-08-29T14:47:58","modified_gmt":"2014-08-29T18:47:58","slug":"friday-fun-read-me-a-story","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/","title":{"rendered":"Friday Fun: Read Me a Story"},"content":{"rendered":"<p><a href=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/12\/announcer.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/12\/announcer.png\" alt=\"announcer\" width=\"143\" height=\"177\" class=\"alignleft size-full wp-image-2650\" \/><\/a> A few days ago, someone on Twitter humorously lamented the fact that I expected them to actually <em>read <\/em>a blog post. After the laughter subsided I thought, well why does he have to? Perhaps I can make it easier for him. Plus I needed something fun for today. So I put together a PowerShell function I call Invoke-BlogReader which I think you'll have fun playing with. It isn't 100% perfect and as with most Friday Fun posts, serves more as an educational device than anything.<\/p>\n<p>The function uses the .NET System.Speech class which seems to be a bit easier to use than legacy COM alternative. Here's a snippet you can test.<\/p>\n<pre class=\"lang:ps decode:true \" >Add-Type -AssemblyName System.speech\r\n$voice = New-Object System.Speech.Synthesis.SpeechSynthesizer\r\n$voice.Speak(\"Hello. I am $($voice.voice.Name)\")\r\n<\/pre>\n<p>So basically, all I have to do is get the contents of a blog article and pass the text to the voice object. That is a bit easier said than done which you'll see as you look through this code.<\/p>\n<pre class=\"lang:ps decode:true \" >\r\n#Requires -version 3.0\r\n\r\nFunction Invoke-BlogReader {\r\n\r\n[cmdletbinding()]\r\nParam(\r\n[Parameter(Position=0,Mandatory,HelpMessage=\"Enter the blog post URL\")]\r\n[ValidateNotNullorEmpty()]\r\n[string]$Url,\r\n[ValidateScript({$_ -ge 1})]\r\n[int]$Count = 5,\r\n[switch]$ShowText,\r\n[validateSet(\"Male\",\"Female\")]\r\n[string]$Gender=\"Male\"\r\n)\r\n\r\nWrite-Verbose -Message \"Starting $($MyInvocation.Mycommand)\"  \r\n\r\nTry {\r\n    Write-Verbose \"Requesting $url\"\r\n    $web = Invoke-WebRequest -Uri $url -DisableKeepAlive -ErrorAction Stop \r\n\r\n    Write-Verbose \"Selecting content\"\r\n    $content = $web.ParsedHtml.getElementsByTagName(\"div\") |\r\n     where {$_.classname -match'entry-content|post-content'} | \r\n     Select -first 1\r\n}\r\nCatch {\r\n    Write-Warning \"Failed to retrieve content from $url\"\r\n    #bail out\r\n    Return\r\n}\r\n\r\nif ($content) {\r\n\r\n    #define a regex to match sentences\r\n    [regex]$rx=\"(\\S.+?[.!?])(?=\\s+|$)\"  \r\n    Write-Verbose \"Parsing sentences\"\r\n    $sentences = $rx.matches($content.innertext) \r\n\r\n    Write-Verbose \"Adding System.Speech assembly\"\r\n    Add-Type -AssemblyName System.speech\r\n\r\n    Write-Verbose \"Initializing a voice\"\r\n    $voice = New-Object System.Speech.Synthesis.SpeechSynthesizer\r\n\r\n    $voice.SelectVoiceByHints($gender)\r\n\r\n    Write-Verbose \"Speaking\"\r\n    $voice.Speak($($web.ParsedHtml.title))\r\n    $voice.speak(\"Published on $($web.ParsedHtml.lastModified)\")\r\n    Write-Verbose \"Here are the first $count lines\"     \r\n    for ($i=0 ;$i -lt $count;$i++) {\r\n      $text = $sentences[$i].Value\r\n      if ($ShowText) {\r\n        write-host \"$text \" -NoNewline\r\n        }\r\n      $voice.speak($text)\r\n     }\r\n     write-host \"`n\"\r\n}\r\nelse {\r\n  Write-Warning \"No web content found\"\r\n}\r\n\r\n#clean up\r\n$voice.Dispose()\r\n\r\nWrite-Verbose -Message \"Ending $($MyInvocation.Mycommand)\"  \r\n} #end function\r\n<\/pre>\n<p>The function uses the Invoke-WebRequest cmdlet to retrieve the content from the specified web page and I then parse the HTML looking for the content.<\/p>\n<pre class=\"lang:ps decode:true \" >$web = Invoke-WebRequest -Uri $url -DisableKeepAlive -ErrorAction Stop \r\nWrite-Verbose \"Selecting content\"\r\n$content = $web.ParsedHtml.getElementsByTagName(\"div\") |\r\nwhere {$_.classname -match'entry-content|post-content'} | \r\nSelect -first 1<\/pre>\n<p>This is the trickiest part because different blogs and sites use different tags and classes. There is a getElementsbyClassName method, but that seems to be hit and miss for me, so I've opted for the slower but consistent process of using Where-Object.<\/p>\n<p>Once I have the content, I could simply pass the text, but I realized I may not want to listen to the entire post. Especially for my own which often have script samples. Those aren't very pleasant to listen to. So I realized I needed to parse the content into sentences. Regular expressions to the rescue.<\/p>\n<pre class=\"lang:ps decode:true \" >[regex]$rx=\"(\\S.+?[.!?])(?=\\s+|$)\"  \r\nWrite-Verbose \"Parsing sentences\"\r\n$sentences = $rx.matches($content.innertext) <\/pre>\n<p>Don't ask me to explain the regex pattern. I \"found\" it and it works. That's all that matters. $Sentences is an array of regex match objects. All I need to do is pass the value from each match to the voice object. The other benefit is that I can include a parameter to also display the text as it is being read.<\/p>\n<pre class=\"lang:ps decode:true \" >  for ($i=0 ;$i -lt $count;$i++) {\r\n      $text = $sentences[$i].Value\r\n      if ($ShowText) {\r\n        write-host \"$text \" -NoNewline\r\n        }\r\n      $voice.speak($text)\r\n     }<\/pre>\n<p>That's all there is to it! If you want to try out all of the options here's a sample command:<\/p>\n<pre class=\"lang:ps decode:true \" >$paramHash = @{\r\n Url = \"http:\/\/blogs.msdn.com\/b\/powershell\/archive\/2014\/08\/27\/powershell-summit-europe-2014.aspx\"\r\n Count = 5\r\n Gender = \"Female\"\r\n ShowText = $True\r\n Verbose = $True\r\n}\r\n\r\nInvoke-BlogReader @paramHash<\/pre>\n<p>Where this can get really fun is using another function, which I'm not sure I ever posted here, to get items from an RSS feed.<\/p>\n<pre class=\"lang:ps decode:true \" >#requires -version 3.0\r\n\r\nFunction Get-RSSFeed {\r\n\r\nParam (\r\n[Parameter(Position=0,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]\r\n[ValidateNotNullOrEmpty()]\r\n[ValidatePattern(\"^http\")]\r\n[Alias('url')]\r\n[string[]]$Path=\"http:\/\/feeds.feedburner.com\/JeffsScriptingBlogAndMore\"\r\n)\r\n\r\nBegin {\r\n    Write-Verbose -Message \"Starting $($MyInvocation.Mycommand)\"  \r\n} #begin\r\n\r\nProcess {\r\n    foreach ($item in $path) {\r\n        $data = Invoke-RestMethod -Uri $item\r\n        foreach ($entry in $data) {\r\n            #create a custom object\r\n            [pscustomobject][ordered]@{\r\n                Title = $entry.title\r\n                Published = $entry.pubDate -as [datetime]\r\n                Link = $entry.origLink\r\n\r\n            } #hash\r\n\r\n        } #foreach entry\r\n    } #foreach item\r\n\r\n} #process\r\n\r\nEnd {\r\n    Write-Verbose -Message \"Ending $($MyInvocation.Mycommand)\"\r\n} #end\r\n\r\n} #end Get-RSSFeed<\/pre>\n<p>Putting it all together you can get the feed, pipe it to Out-Gridview, select one and have the blog read to you!<\/p>\n<pre class=\"lang:ps decode:true \" >get-rssfeed | out-gridview -OutputMode Single | foreach { Invoke-BlogReader $_.link -Count 5}  <\/pre>\n<p>So now you can have your blog and listen to! There are probably a number of ways this could be enhanced. Or perhaps you want to take some of these concepts and techniques in another direction. If so, I hope you'll let me know where you end up. Have a great weekend.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few days ago, someone on Twitter humorously lamented the fact that I expected them to actually read a blog post. After the laughter subsided I thought, well why does he have to? Perhaps I can make it easier for him. Plus I needed something fun for today. So I put together a PowerShell function&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"NEW! Friday Fun: Read Me a Story http:\/\/wp.me\/p1nF6U-12e #PowerShell","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[271,4,359,8],"tags":[568,410,534,473,540,451],"class_list":["post-3982","post","type-post","status-publish","format-standard","hentry","category-friday-fun","category-powershell","category-powershell-3-0","category-scripting","tag-friday-fun","tag-invoke-webrequest","tag-powershell","tag-rss","tag-scripting","tag-speech"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Friday Fun: Read Me a Story &#8226; The Lonely Administrator<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Friday Fun: Read Me a Story &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"A few days ago, someone on Twitter humorously lamented the fact that I expected them to actually read a blog post. After the laughter subsided I thought, well why does he have to? Perhaps I can make it easier for him. Plus I needed something fun for today. So I put together a PowerShell function...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2014-08-29T18:47:58+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/12\/announcer.png\" \/>\n<meta name=\"author\" content=\"Jeffery Hicks\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:site\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeffery Hicks\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"Friday Fun: Read Me a Story\",\"datePublished\":\"2014-08-29T18:47:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/\"},\"wordCount\":473,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/12\\\/announcer.png\",\"keywords\":[\"Friday Fun\",\"Invoke-WebRequest\",\"PowerShell\",\"RSS\",\"Scripting\",\"Speech\"],\"articleSection\":[\"Friday Fun\",\"PowerShell\",\"Powershell 3.0\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/\",\"name\":\"Friday Fun: Read Me a Story &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/12\\\/announcer.png\",\"datePublished\":\"2014-08-29T18:47:58+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/#primaryimage\",\"url\":\"http:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/12\\\/announcer.png\",\"contentUrl\":\"http:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/12\\\/announcer.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/3982\\\/friday-fun-read-me-a-story\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Friday Fun\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/friday-fun\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Friday Fun: Read Me a Story\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/\",\"name\":\"The Lonely Administrator\",\"description\":\"Practical Advice for the Automating IT Pro\",\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\",\"name\":\"Jeffery Hicks\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"caption\":\"Jeffery Hicks\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Friday Fun: Read Me a Story &#8226; The Lonely Administrator","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/","og_locale":"en_US","og_type":"article","og_title":"Friday Fun: Read Me a Story &#8226; The Lonely Administrator","og_description":"A few days ago, someone on Twitter humorously lamented the fact that I expected them to actually read a blog post. After the laughter subsided I thought, well why does he have to? Perhaps I can make it easier for him. Plus I needed something fun for today. So I put together a PowerShell function...","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/","og_site_name":"The Lonely Administrator","article_published_time":"2014-08-29T18:47:58+00:00","og_image":[{"url":"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/12\/announcer.png","type":"","width":"","height":""}],"author":"Jeffery Hicks","twitter_card":"summary_large_image","twitter_creator":"@JeffHicks","twitter_site":"@JeffHicks","twitter_misc":{"Written by":"Jeffery Hicks","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"Friday Fun: Read Me a Story","datePublished":"2014-08-29T18:47:58+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/"},"wordCount":473,"commentCount":2,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/#primaryimage"},"thumbnailUrl":"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/12\/announcer.png","keywords":["Friday Fun","Invoke-WebRequest","PowerShell","RSS","Scripting","Speech"],"articleSection":["Friday Fun","PowerShell","Powershell 3.0","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/","name":"Friday Fun: Read Me a Story &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/#primaryimage"},"thumbnailUrl":"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/12\/announcer.png","datePublished":"2014-08-29T18:47:58+00:00","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/#primaryimage","url":"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/12\/announcer.png","contentUrl":"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/12\/announcer.png"},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3982\/friday-fun-read-me-a-story\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Friday Fun","item":"https:\/\/jdhitsolutions.com\/blog\/category\/friday-fun\/"},{"@type":"ListItem","position":2,"name":"Friday Fun: Read Me a Story"}]},{"@type":"WebSite","@id":"https:\/\/jdhitsolutions.com\/blog\/#website","url":"https:\/\/jdhitsolutions.com\/blog\/","name":"The Lonely Administrator","description":"Practical Advice for the Automating IT Pro","publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jdhitsolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9","name":"Jeffery Hicks","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","caption":"Jeffery Hicks"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":3140,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/3140\/friday-fun-quote-of-the-day-revised\/","url_meta":{"origin":3982,"position":0},"title":"Friday Fun: Quote of the Day Revised","author":"Jeffery Hicks","date":"June 28, 2013","format":false,"excerpt":"This week TrainSignal has been running a contest to celebrate my new PowerShell 3.0 course . All you have to do to win is enter some off-the-wall, silly or non-production use of PowerShell. I've posted a few examples on the TrainSignal blog this week. \u00a0These Friday Fun posts I write\u2026","rel":"","context":"In &quot;Friday Fun&quot;","block_context":{"text":"Friday Fun","link":"https:\/\/jdhitsolutions.com\/blog\/category\/friday-fun\/"},"img":{"alt_text":"talkbubble-v3","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/05\/talkbubble-v3-150x150.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":4342,"url":"https:\/\/jdhitsolutions.com\/blog\/friday-fun\/4342\/friday-fun-whats-my-ip\/","url_meta":{"origin":3982,"position":1},"title":"Friday Fun: What&#8217;s My IP","author":"Jeffery Hicks","date":"April 3, 2015","format":false,"excerpt":"Today's Friday Fun is a \"quick and dirty\" solution to the question, \"What is my public IP address?\" There are plenty of web sites and services you can visit that will display that piece of information. Naturally I want an easy way to get this in PowerShell. Recently I came\u2026","rel":"","context":"In &quot;Friday Fun&quot;","block_context":{"text":"Friday Fun","link":"https:\/\/jdhitsolutions.com\/blog\/category\/friday-fun\/"},"img":{"alt_text":"getmyip","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2015\/04\/getmyip-1024x345.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":4061,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/4061\/friday-fun-lets-play-a-game\/","url_meta":{"origin":3982,"position":2},"title":"Friday Fun &#8211; Let&#8217;s Play a Game","author":"Jeffery Hicks","date":"October 3, 2014","format":false,"excerpt":"Today is going to be a lot of fun. A few years ago, back when we were still running PowerShell 2.0 everywhere, I created a module to run a Bingo game in a PowerShell session. I primarily wrote the module as a learning tool for beginners wanting to know more\u2026","rel":"","context":"In &quot;Friday Fun&quot;","block_context":{"text":"Friday Fun","link":"https:\/\/jdhitsolutions.com\/blog\/category\/friday-fun\/"},"img":{"alt_text":"BingoCard-small","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2014\/10\/BingoCard-small.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":3455,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/3455\/friday-fun-color-my-web\/","url_meta":{"origin":3982,"position":3},"title":"Friday Fun Color My Web","author":"Jeffery Hicks","date":"September 20, 2013","format":false,"excerpt":"Awhile ago I posted an article demonstrating using Invoke-Webrequest which is part of PowerShell 3.0. I used the page at Manning.com to display the Print and MEAP bestsellers. By the way, thanks to all of you who keep making PowerShell books popular. My original script simply wrote the results to\u2026","rel":"","context":"In &quot;Books&quot;","block_context":{"text":"Books","link":"https:\/\/jdhitsolutions.com\/blog\/category\/books\/"},"img":{"alt_text":"get-manningbestseller1","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2013\/09\/get-manningbestseller1-1024x606.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2013\/09\/get-manningbestseller1-1024x606.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2013\/09\/get-manningbestseller1-1024x606.png?resize=525%2C300 1.5x"},"classes":[]},{"id":4184,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/4184\/friday-fun-search-me\/","url_meta":{"origin":3982,"position":4},"title":"Friday Fun: Search Me","author":"Jeffery Hicks","date":"January 16, 2015","format":false,"excerpt":"I've been working on a few revisions and additions to my ISE Scripting Geek module. Even though what I'm about to show you will eventually be available in a future release of that module, I thought I'd share it with you today. One of the things I wanted to be\u2026","rel":"","context":"In &quot;Friday Fun&quot;","block_context":{"text":"Friday Fun","link":"https:\/\/jdhitsolutions.com\/blog\/category\/friday-fun\/"},"img":{"alt_text":"magnifying-glass-text-label-search","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2013\/01\/magnifying-glass-text-label-search-150x150.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1185,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/1185\/friday-fun-get-messagebox\/","url_meta":{"origin":3982,"position":5},"title":"Friday Fun Get MessageBox","author":"Jeffery Hicks","date":"March 4, 2011","format":false,"excerpt":"Today's Friday Fun offers a way for you to graphically interact with your PowerShell scripts and functions without resorting to a lot of complex Winform scripting. I have a function that you can use to display an interactive message box complete with buttons like Yes, No or Cancel. You can\u2026","rel":"","context":"In &quot;Friday Fun&quot;","block_context":{"text":"Friday Fun","link":"https:\/\/jdhitsolutions.com\/blog\/category\/friday-fun\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2011\/03\/msgbox.png?resize=350%2C200","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/3982","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=3982"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/3982\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=3982"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=3982"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=3982"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}