{"id":245,"date":"2018-03-01T00:00:38","date_gmt":"2018-03-01T08:00:38","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/koryt\/?p=245"},"modified":"2020-04-29T10:09:00","modified_gmt":"2020-04-29T17:09:00","slug":"powershell-for-programmers-strings-quotes-and-quirks","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/powershell-for-programmers-strings-quotes-and-quirks\/","title":{"rendered":"PowerShell For Programmers: Strings, Quotes and Quirks"},"content":{"rendered":"<p><span style=\"font-size: 12pt;\">Welcome back everyone! This will be a short, but important entry for the guide. <\/span><\/p>\n<p><span style=\"font-size: 12pt;\">The difference between quote characters is something I\u2019m asked about all the time. It is important to understand in PowerShell, but most of the time it probably won\u2019t make a difference. <\/span><\/p>\n<p><span style=\"text-decoration: underline; font-size: 12pt;\"><strong>TLDR:<\/strong> If you&#8217;re just typing a value like &#8220;alg&#8221; then it doesn&#8217;t matter, but if you have any special symbols you can see the difference. <\/span><\/p>\n<h2>Single vs. Double Quotes<\/h2>\n<p><span style=\"font-size: 12pt;\">We refer to single quotes as Literal Strings and double quotes as Expandable Strings. Both create the same datatype (system.string), but a double quote will expand any special character and a single quote will use the literal characters you typed. <\/span><\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:63f31c3f-767e-40d0-8af4-97c0fe4d737e\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true \"><span style=\"font-size: 12pt;\">$a = \"test\"\r\n\r\n\"A is $a\"\r\n\r\n'A is $a'\r\n<\/span><\/pre>\n<\/div>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:4fd5893a-30f5-4f51-83cb-fdf4df0697a6\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true \"><span style=\"font-size: 12pt;\">A is test\r\nA is $a<\/span><\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<h2>Variable Sub-Expressions<\/h2>\n<p><span style=\"font-size: 12pt;\">With an expandable string, you might run into some unintended behavior when you try to access a property of a variable (or do some other kinds of special actions). In these scenarios we need to use a variable sub expression or string concatenation (+ sign concatenates and so does -join). A sub expression uses $() to surround the special code we want to run inside our expandable string:<\/span><\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:93cb9d4c-4d9d-40c5-9b9f-17b50fd623d8\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true\"><span style=\"font-size: 12pt;\">$service = get-service alg\r\n\"Service: $service\"<\/span><\/pre>\n<\/div>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:943dcf5d-5a06-4844-80b8-51bd7ca47e75\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:default decode:true\"><span style=\"font-size: 12pt;\">Service: System.ServiceProcess.ServiceController<\/span><\/pre>\n<\/div>\n<blockquote><p><span style=\"font-size: 12pt;\">That doesn\u2019t look right!<\/span><\/p><\/blockquote>\n<p><span style=\"font-size: 12pt;\">When PowerShell isn\u2019t sure how to convert something to a string, it just shows you the data type you gave it. <\/span><\/p>\n<blockquote><p><span style=\"font-size: 12pt;\">\u201cNo problem, I\u2019ll just access the property I want!\u201d ~Every programmer ever<\/span><\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:036b12bd-798d-444b-842f-0e1f1ea4ccff\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true \"><span style=\"font-size: 12pt;\">\"Service: $service.Name\"<\/span><\/pre>\n<\/div>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:fcc6cbdc-82dd-49c5-b31a-f173e507a31f\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true\"><span style=\"font-size: 12pt;\">Service: System.ServiceProcess.ServiceController.Name<\/span><\/pre>\n<\/div>\n<p><span style=\"font-size: 12pt;\">Not quite what we were expecting <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-sadsmile\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2018\/01\/wlEmoticon-sadsmile1.png\" alt=\"Sad smile\" \/><\/span><\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:bdf46469-c3af-45dd-93c7-349c5a6aa9f2\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true\"><span style=\"font-size: 12pt;\">\"Service: $($Service.Name)\"<\/span><\/pre>\n<\/div>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:d6624a35-7295-4887-b814-434f4d556da1\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:default decode:true \"><span style=\"font-size: 12pt;\">Service: alg<\/span><\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<blockquote><p><span style=\"font-size: 12pt;\">Eureka! <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-openmouthedsmile\" src=\"https:\/\/devdevblogs.wpengine.com\/wp-content\/uploads\/sites\/32\/2019\/10\/wlEmoticon-openmouthedsmile1.png\" alt=\"Open-mouthed smile\" \/><\/span><\/p><\/blockquote>\n<p><span style=\"font-size: 12pt;\">This allows us to run code as well:<\/span><\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f2a77551-7beb-4320-a3e5-9f11c10ac747\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true \"><span style=\"font-size: 12pt;\">\"Date: $(get-date)\"<\/span><\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:7a617830-42b5-49cd-9a93-63feade1e381\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:default decode:true \"><span style=\"font-size: 12pt;\">Date: 01\/24\/2018 11:01:15<\/span><\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p><span style=\"font-size: 12pt;\">Now this solves the problem and allows us to write properties of our objects into strings. <\/span><\/p>\n<h2>Simple String Manipulation<\/h2>\n<p><span style=\"font-size: 12pt;\">As I mentioned, concatenation also works. We can concatenate strings via the + sign, or \u2013join operator.<\/span><\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:7bc70f1e-7771-4701-8639-599396191e0c\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true\"><span style=\"font-size: 12pt;\">\"Service: \" + $Service.Name\r\n\"Service\",$Service.Name -join \": \" #you can join with any delimeter<\/span><\/pre>\n<\/div>\n<p><span style=\"font-size: 12pt;\">We also have operators <u>and methods<\/u> for split and replace. The operators use <a href=\"https:\/\/docs.microsoft.com\/en-us\/powershell\/module\/microsoft.powershell.core\/about\/about_regular_expressions?view=powershell-5.1\" target=\"_blank\" rel=\"noopener noreferrer\">Regex<\/a> and the methods do not. (I can do a post on regex in the future)<\/span><\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f52a8d37-5d36-4a2d-99f3-41bb87f86d55\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true\"><span style=\"font-size: 12pt;\">\"a,b,c,d,e\" -split \",\"\r\n\"a,b,c,d,e\".Split(\",\")\r\n\r\n\"a,b,c,d,e\" -replace \",\",\";\"\r\n\"a,b,c,d,e\".Replace(\",\",\";\")<\/span><\/pre>\n<\/div>\n<p><span style=\"font-size: 12pt;\">Feel free to pipe any string into Get-Member to see some of the other methods you might be familiar with and looking for. <\/span><\/p>\n<h2>Format Operator<\/h2>\n<p><span style=\"font-size: 12pt;\">The format operator gets some pretty heavy use in C# and it lives here in PowerShell as well. If you\u2019re unfamiliar with it, the idea is that we want to put placeholders in our string and populate them with values from an array later. <\/span><\/p>\n<p><span style=\"font-size: 12pt;\">So, if we wanted to write out a bunch of comma-separated properties of an object we could do something like this:<\/span><\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:1240eff7-555c-4ac8-97ba-b0168558b4ad\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true \"><span style=\"font-size: 12pt;\"># -f\r\n\"{0},{1},{2}\" -f $service.DisplayName,$service.StartType,$service.Status<\/span><\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p><span style=\"font-size: 12pt;\">Notice the place holders are a set of curly braces {} with an index number inside. They don\u2019t have to be in order, and they can be reused. <\/span><\/p>\n<p><span style=\"font-size: 12pt;\">We can also force specific format codes onto the data:<\/span><\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:e5387210-bce9-490a-88b3-115a565a470e\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true \"><span style=\"font-size: 12pt;\">#c is the code for currency\r\n\"Cost: {0:c}\" -f 502342420.12<\/span><\/pre>\n<p><span style=\"font-size: 12pt;\">you can find the other codes <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/standard\/base-types\/formatting-types\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>, but its a bit annoying to get through.<\/span><\/p>\n<\/div>\n<p><span style=\"font-size: 12pt;\">I personally don\u2019t like to use the format operator very often, but it can do some pretty unique and impressive things when you need it. I found <a href=\"https:\/\/social.technet.microsoft.com\/wiki\/contents\/articles\/7855.powershell-using-the-f-format-operator.aspx\" target=\"_blank\" rel=\"noopener noreferrer\">this<\/a> blog post to have a great reference about extra format operator information so I figured linking it would be better than reinventing the wheel. <\/span><\/p>\n<p><span style=\"font-size: 12pt;\">\u00a0<\/span><\/p>\n<p><span style=\"font-size: 12pt;\">Well that\u2019s all for now, hopefully this helps you on your PowerShell journey and helps you determine which quotes you need to use as well as get some useful manipulation done. I\u2019ll be addressing another kind of string, called a \u201cHere\u201d string in a short section later.<\/span><\/p>\n<p><span style=\"font-size: 12pt;\">I\u2019ll be adding to the series to cover other quirks as well so let me know in the comments if there is any particular topics confusing you!<\/span><\/p>\n<p><span style=\"font-size: 12pt;\">If you find this helpful don&#8217;t forget to rate, comment and share\u00a0\ud83d\ude42<\/span><\/p>\n<p><span style=\"font-size: 12pt;\">For the main series post, check back <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/powershell-for-programmers-a-quick-start-guide\/\">here.<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Welcome back everyone! This will be a short, but important entry for the guide. The difference between quote characters is something I\u2019m asked about all the time. It is important to understand in PowerShell, but most of the time it probably won\u2019t make a difference. TLDR: If you&#8217;re just typing a value like &#8220;alg&#8221; then [&hellip;]<\/p>\n","protected":false},"author":7300,"featured_media":87096,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1738,2126],"tags":[2221,2125],"class_list":["post-245","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","category-powershell_for_programmers","tag-kory-thacher","tag-koryt"],"acf":[],"blog_post_summary":"<p>Welcome back everyone! This will be a short, but important entry for the guide. The difference between quote characters is something I\u2019m asked about all the time. It is important to understand in PowerShell, but most of the time it probably won\u2019t make a difference. TLDR: If you&#8217;re just typing a value like &#8220;alg&#8221; then [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/7300"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=245"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/245\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}