{"id":9801,"date":"2006-08-21T21:21:00","date_gmt":"2006-08-21T21:21:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2006\/08\/21\/fun-with-powershell-character-manipulation\/"},"modified":"2019-02-18T13:21:25","modified_gmt":"2019-02-18T20:21:25","slug":"fun-with-powershell-character-manipulation","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/fun-with-powershell-character-manipulation\/","title":{"rendered":"Fun with PowerShell &#8211; character manipulation&#8230;"},"content":{"rendered":"<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">I was investigating a localization test failure today and ran into the following error message:<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span>&#8216;actual error is <\/span><span>\u614c<\/span><span>\u7220\u6361\u6e69<\/span><span>\u2065<\/span><span>\u6564\u6c20\u6365\u6574\u7275<\/span><span>\uae20<\/span><span>\u45ff<\/span><span>\u5c3a<\/span><span>\uafff\u6e20<\/span><span>\u6527\u6978\u7473<\/span><span>\u2065<\/span><span>\u6170<\/span><span>\u2073<\/span><span>\u756f\u6e20<\/span><span>\u6527\u7473\u7020\u7361\u7520<\/span><span>\u206e<\/span><span>\u6f64<\/span><span>\u7373\u6569<\/span><span>\u2e72\u0a0d, expected &#8216;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">Since it was failing in the French locale, getting what appeared to be a Chinese error message didn\u2019t make a lot of sense. A coworker confirmed that it was garbage. My next guess was that it was actually an ANSI string that was mangled into Unicode. In other words, two characters in the source string became one character in the output. But how to test this? Well \u2013 fortunately we have PowerShell! I pasted the string into the console window which looked like:<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><\/span><span lang=\"EN-CA\"><font face=\"Calibri\">$t = &#8216;??????????????????????????????????&#8217;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">And then used casts to take the string apart:<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><\/span><span lang=\"EN-CA\"><font face=\"Calibri\">&amp;{$ofs=&#8221;; [string][char[]] ([int[]] [char[]] $t |% { $_ -band 0xff ;<span>&nbsp; <\/span>[int] ($_ \/ 256 ) })}<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">Running this exercise in stunt-casting translated $t back into:<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">La racine de lecteur r\u00ffF:\\\u00ff\u00b0 n&#8217;existe pas ou n&#8217;est pas un dossier.<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">Now that\u2019s more like the error message one would expect in the French locale <\/font><\/span><span lang=\"EN-CA\"><span>J<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><span><\/span><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">Anyone want to take a stab at explaining how this works?<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">-bruce<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\"><\/font><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-CA\"><font face=\"Calibri\">Bruce Payette&nbsp;[MSFT]<br \/>Windows PowerShell Tech Lead<\/font><\/span><span lang=\"EN-CA\"><font face=\"Calibri\"><br \/>Visit the Windows PowerShell ScriptCenter at:&nbsp; <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx\"><strong><font color=\"#006bad\">http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx<\/font><\/strong><\/a><\/font><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was investigating a localization test failure today and ran into the following error message: &nbsp; &#8216;actual error is \u614c\u7220\u6361\u6e69\u2065\u6564\u6c20\u6365\u6574\u7275\uae20\u45ff\u5c3a\uafff\u6e20\u6527\u6978\u7473\u2065\u6170\u2073\u756f\u6e20\u6527\u7473\u7020\u7361\u7520\u206e\u6f64\u7373\u6569\u2e72\u0a0d, expected &#8216; &nbsp; Since it was failing in the French locale, getting what appeared to be a Chinese error message didn\u2019t make a lot of sense. A coworker confirmed that it was garbage. My next [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-9801","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell"],"acf":[],"blog_post_summary":"<p>I was investigating a localization test failure today and ran into the following error message: &nbsp; &#8216;actual error is \u614c\u7220\u6361\u6e69\u2065\u6564\u6c20\u6365\u6574\u7275\uae20\u45ff\u5c3a\uafff\u6e20\u6527\u6978\u7473\u2065\u6170\u2073\u756f\u6e20\u6527\u7473\u7020\u7361\u7520\u206e\u6f64\u7373\u6569\u2e72\u0a0d, expected &#8216; &nbsp; Since it was failing in the French locale, getting what appeared to be a Chinese error message didn\u2019t make a lot of sense. A coworker confirmed that it was garbage. My next [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/9801","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=9801"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/9801\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=9801"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=9801"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=9801"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}