{"id":206,"date":"2018-02-01T08:56:47","date_gmt":"2018-02-01T16:56:47","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/koryt\/?p=206"},"modified":"2020-04-29T09:59:39","modified_gmt":"2020-04-29T16:59:39","slug":"powershell-for-programmers-what-happened-to-my-operators","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/powershell-for-programmers-what-happened-to-my-operators\/","title":{"rendered":"PowerShell for Programmers: What happened to my operators?"},"content":{"rendered":"<p>Operators are one of the most frustrating things about learning PowerShell if you\u2019re coming from just about any other language in existence. Operators like ==, &lt;=, !=. etc. are almost ubiquitous in programming, but none of them are supported in PowerShell.<\/p>\n<p>This can lead to some pretty frustrating errors with things like If statements. You might see:<\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f848e68c-fc63-4ad1-86cb-6478049cb823\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:default decode:true \">The assignment expression is not valid. The input to an assignment operator must\r\nbe an object that is able to accept assignments, such as a variable or a property.\r\n\r\nUnexpected token ')' in expression or statement.<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p>In PowerShell we are still going to <em>have<\/em> all these operators, they are just going to <em>look<\/em> different, using dashes and vaguely resembling parameters.<\/p>\n<p>I wondered the reason behind this myself for a while, and made a pretty inaccurate guess, but a coworker of mine recently shared the answer from Jeffrey Snover himself, who was gracious enough to let me post it here:<\/p>\n<blockquote><p>What was the rationale behind using \u2013eq, -le, -gt, etc. vs. the traditional ==, &lt;=, &gt; found in most languages?<\/p>\n<p><span style=\"color: #ff0000;\">Bruce Payette\u2019s book PowerShell in Action goes into this in detail. The basic idea is that as soon as you choose \u201c&gt;\u201d for redirection, you are forced down the \u2013lt path. That is why I originally tried to use \u201c:&gt;\u201d for redirection so that we could use &gt;=, etc but the community went absolutely ape-@$# over this and thus we are where we are.<\/span><\/p><\/blockquote>\n<p><span style=\"color: #000000;\">Lets take a look at what we have to work with:<\/span><\/p>\n<h3>Comparison and logical operators:<\/h3>\n<ul>\n<li>No case sensitivity (\u201cH\u201d would be equal with \u201ch\u201d) on comparison operators<\/li>\n<li>No wild card support on comparison operators<\/li>\n<\/ul>\n<div style=\"line-height: normal; direction: ltr;\">\n<p>&nbsp;<\/p>\n<table title=\"\" border=\"1\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"96\">&nbsp;<\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\"><strong>Usual<\/strong><\/span><\/p>\n<\/td>\n<td width=\"131\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\"><strong>PowerShell<\/strong><\/span><\/p>\n<\/td>\n<td width=\"236\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\"><strong>Test<\/strong> <strong>\nperformed<\/strong><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"96\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">==<\/span><\/p>\n<\/td>\n<td width=\"129\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">-eq<\/span><\/p>\n<\/td>\n<td width=\"239\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">Equality<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"96\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">!=<\/span><\/p>\n<\/td>\n<td width=\"129\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">-ne<\/span><\/p>\n<\/td>\n<td width=\"239\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">Non\nEquality<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"96\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">&gt;<\/span><\/p>\n<\/td>\n<td width=\"129\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">-gt<\/span><\/p>\n<\/td>\n<td width=\"239\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">Greater\nThan<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"96\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">&gt;=<\/span><\/p>\n<\/td>\n<td width=\"129\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">-ge<\/span><\/p>\n<\/td>\n<td width=\"251\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">Greater Than OR Equal\nTo<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"96\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">&lt;<\/span><\/p>\n<\/td>\n<td width=\"129\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">-lt<\/span><\/p>\n<\/td>\n<td width=\"239\">&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">Less Than<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"96\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">&lt;=<\/span><\/p>\n<\/td>\n<td width=\"129\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">-le<\/span><\/p>\n<\/td>\n<td width=\"243\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">Less Than OR Equal\nTo<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"96\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">!<\/span><\/p>\n<\/td>\n<td width=\"129\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">! OR -not<\/span><\/p>\n<\/td>\n<td width=\"239\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">Not<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"96\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">||<\/span><\/p>\n<\/td>\n<td width=\"129\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">-or<\/span><\/p>\n<\/td>\n<td width=\"239\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">Logical\nOr<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"96\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">&amp;&amp;<\/span><\/p>\n<\/td>\n<td width=\"129\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">-and<\/span><\/p>\n<\/td>\n<td width=\"239\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">Logical\nAnd<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"96\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">^<\/span><\/p>\n<\/td>\n<td width=\"129\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">-xor<\/span><\/p>\n<\/td>\n<td width=\"243\"><span style=\"font-size: 12pt;\">\n<\/span><\/p>\n<p style=\"margin: 0in;\"><span style=\"font-size: 12pt;\">Logical Exclusive\nOr<\/span><\/p>\n<p>&nbsp;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<\/div>\n<p>&nbsp;<\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:4c6bc60d-d094-4971-9cf4-23f91b502f7e\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true \">#So, this won't work:\r\nIf(1 == 1)\r\n{\r\nwrite-host \"Hello World\" -ForegroundColor Cyan\r\n}\r\n\r\n#Instead you need:\r\nIf(1 -eq 1)\r\n{\r\nwrite-host \"Hello World\" -ForegroundColor Cyan\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Its not so hard, but it will be quite an adjustment, so get used to seeing errors here.<\/p>\n<blockquote><p>\u201cBut I want wild cards!\u201d<\/p><\/blockquote>\n<p>No worries, PowerShell has you covered here too. You can use wild cards with an alternate set of comparison operators.<\/p>\n<p>Instead of \u2013eq\/-neq we will use \u2013like\/-notlike to enable windows wild card support:<\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:5c7d5f67-0506-4235-a36c-653d0a1b92de\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<p>&nbsp;<\/p>\n<pre class=\"lang:ps decode:true\">#no wild cards: literal *\r\nIf(\"hello\" -eq \"h*\")\r\n{\r\nwrite-host \"equal!\" -ForegroundColor green\r\n}\r\nelse\r\n{\r\nwrite-host \"not equal!\" -ForegroundColor red\r\n}\r\n\r\n#wild cards enabled\r\nIf(\"hello\" -like \"h*\")\r\n{\r\nwrite-host \"equal!\" -ForegroundColor green\r\n}\r\nelse\r\n{\r\nwrite-host \"not equal!\" -ForegroundColor red\r\n}<\/pre>\n<\/div>\n<p><span style=\"color: #000000;\">\u00a0<\/span><\/p>\n<p><span style=\"color: #000000;\">If you want RegEx we have \u2013Match\/-NotMatch:<\/span><\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:e16817f1-fa81-413e-ae7f-a09748b78693\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true\">#Check pattern\r\nIf(\"I've got 1 digit inside!\" -match \"\\d\")\r\n{\r\nwrite-host \"match!\" -ForegroundColor green\r\n#cool way to see *what* matched (will only pull the first match)\r\n$matches[0]\r\n}<span style=\"color: #000000; font-family: Arimo, 'Helvetica Neue', Arial, sans-serif; font-size: 1rem; background-color: #f7f7f9;\">\u00a0<\/span><\/pre>\n<\/div>\n<p>Additionally, you might find yourself seeing people use operators you are not used to having.<\/p>\n<ul>\n<li>-is, -isnot to check data types<\/li>\n<li>-in, -contains, -notin, -notcontains to check for values in lists<\/li>\n<\/ul>\n<blockquote><p><span style=\"color: #000000;\">\u201cBut I need case sensitivity!\u201d<\/span><\/p><\/blockquote>\n<p><span style=\"color: #000000;\">To make any of the comparison operators case sensitive, you can add a \u201cc\u201d prefix. \u2013eq becomes \u2013ceq. \u2013Like becomes \u2013clike and so on.<\/span><\/p>\n<div id=\"scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:43269d69-eca2-413d-a371-50d8b8a80673\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; padding: 0px; float: none;\">\n<pre class=\"lang:ps decode:true \">#wild cards + case sensitivity\r\nIf(\"hello\" -clike \"H*\")\r\n{\r\nwrite-host \"equal!\" -ForegroundColor green\r\n}\r\nelse\r\n{\r\nwrite-host \"not equal!\" -ForegroundColor red\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p><span style=\"color: #000000;\">\u00a0<\/span><\/p>\n<p>Well that\u2019s all for now, hopefully this helps you on your PowerShell journey and fixes some issues you may have run into from diving in. 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!<\/p>\n<p>If you find this helpful don&#8217;t forget to rate, comment and share\u00a0\ud83d\ude42<\/p>\n<p>For the main series post, check back <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/powershell-for-programmers-a-quick-start-guide\/\">here.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Operators are one of the most frustrating things about learning PowerShell if you\u2019re coming from just about any other language in existence. Operators like ==, &lt;=, !=. etc. are almost ubiquitous in programming, but none of them are supported in PowerShell. This can lead to some pretty frustrating errors with things like If statements. You [&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-206","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>Operators are one of the most frustrating things about learning PowerShell if you\u2019re coming from just about any other language in existence. Operators like ==, &lt;=, !=. etc. are almost ubiquitous in programming, but none of them are supported in PowerShell. This can lead to some pretty frustrating errors with things like If statements. You [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/206","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=206"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/206\/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=206"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=206"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=206"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}