<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1455897889336399878</id><updated>2015-09-29T09:48:33.654+02:00</updated><category term="powershell"/><category term=".NET"/><category term="security"/><category term="DAPI"/><category term="DNS"/><category term="Exchange 2010"/><category term="Hyper-V"/><category term="Microsoft Exchange"/><category term="Windows 8"/><category term="encryption"/><title type='text'>SysAddict</title><subtitle type='html'>Random thoughts on Windows system administration in general with a focus on Powershell and scripting.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.sysaddict.me/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://www.sysaddict.me/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Frédéric Crespo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-5SUu2r0J2x0/AAAAAAAAAAI/AAAAAAAAAJM/sHCRJukYPxk/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1455897889336399878.post-6752699966125692129</id><published>2014-10-13T22:28:00.000+02:00</published><updated>2014-10-13T22:28:00.814+02:00</updated><title type='text'>Note to self: double check what the network guys are doing</title><content type='html'>You ask twelve servers on each site with two dedicated gigabit network ports per server for replication. You specifically ask LACP to be implemented on these network ports and you specifically tell the network team that the servers will use the replication interface to replicate over the other site.&lt;br /&gt;&lt;br /&gt;When you check the ordered hardware by the networking team you realise they interconnected the switches on both site with a 1 gigabit interface. Duh!</content><link rel='replies' type='application/atom+xml' href='http://www.sysaddict.me/feeds/6752699966125692129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sysaddict.me/2014/10/note-to-self-double-check-what-network.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/6752699966125692129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/6752699966125692129'/><link rel='alternate' type='text/html' href='http://www.sysaddict.me/2014/10/note-to-self-double-check-what-network.html' title='Note to self: double check what the network guys are doing'/><author><name>Frédéric Crespo</name><uri>https://plus.google.com/103200571988806930208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-5SUu2r0J2x0/AAAAAAAAAAI/AAAAAAAAAJM/sHCRJukYPxk/s512-c/photo.jpg'/></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1"/><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD"/></entry><entry><id>tag:blogger.com,1999:blog-1455897889336399878.post-5600267655122725532</id><published>2013-12-16T21:34:00.000+01:00</published><updated>2013-12-16T21:51:59.747+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Exchange 2010"/><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft Exchange"/><category scheme="http://www.blogger.com/atom/ns#" term="powershell"/><title type='text'>How to get distribution group members recursively with powershell?</title><content type='html'>On a current Migration project from an Exchange 2010 forest to another I was asked to migrate existing distribution groups containing multiple levels of nesting to flat distribution groups. Thought you&#39;d be able to do this with a one-liner based on the &lt;b&gt;Get-DistributionGroupMember&lt;/b&gt; cmdlet?  &lt;br /&gt;&lt;h3&gt;&lt;/h3&gt;&lt;h3&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3&gt;The Problem&lt;/h3&gt;&lt;div&gt;Unfortunately &lt;b&gt;Get-DistributionGroupMemer&lt;/b&gt; does not provide a -recusive switch nor does the &lt;b&gt;Get-Member&lt;/b&gt; cmdlet. So in order to retrieve every member you will have to come up with your own recusive definition. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However two things could turn up badly when doing so.&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;You could very well include a single member several times as he could be a member of several nested distribution groups.&lt;/li&gt;&lt;li&gt;You could also go on ad infinitum if you don&#39;t pay attention to the fact that a group can be a member of one of his members group.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;With a clean solution to the above two points the rest is just a basic recusive definition. Let&#39;s move on to the solution of the above two points.&lt;/div&gt;&lt;/div&gt;&lt;h3&gt;&lt;/h3&gt;&lt;h3&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3&gt;The Solution&lt;/h3&gt;&lt;div&gt;Technically, I guess, there are many ways to address the above problems. However one way or another it will end-up being some kind of memory implementation.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You want to know if you already visited a group and skip it if it is the case and you want to know which members you already accounted for.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I decided to go with two lists:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;a &lt;i&gt;members&lt;/i&gt; list that would contain all members I want to collect.&lt;/li&gt;&lt;li&gt;a &lt;i&gt;processed&lt;/i&gt; list that would contain all groups I already processed.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Technically I decided to go for &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb359438(v=vs.110).aspx&quot;&gt;HashSets&lt;/a&gt; that would contain the&lt;i&gt; members &lt;/i&gt;and &lt;i&gt;processed&lt;/i&gt; elements. The reason being as follows:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Since it is a set I don&#39;t need to worry about adding a member several times because the data structure will protect me from this.&lt;/li&gt;&lt;li&gt;I can spare myself some coding since I can both add a new element and test if it was already there in only one instruction (as can be seen below).&lt;/li&gt;&lt;li&gt;Since it is a&lt;b&gt; Hash&lt;/b&gt;Set it is quite optimized which is a bonus.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h3&gt;&lt;/h3&gt;&lt;h3&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3&gt;The Script&lt;/h3&gt;&lt;div&gt;The below script is just an example and doesn&#39;t actually do anything with the members but printing them on the console.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To test it simply save it into a .ps1 file and change the group name on the third line with whatever group you want to list the members of instead of &lt;i&gt;TestRoot.&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class=&quot;brush: ps&quot;&gt;Add-Type -AssemblyName System.Core&lt;br /&gt; &lt;br /&gt;$group = Get-Group &quot;TestRoot&quot;&lt;br /&gt;$members = new-object &#39;System.Collections.Generic.HashSet[string]&#39;&lt;br /&gt;$processed = new-object &#39;System.Collections.Generic.HashSet[string]&#39;&lt;br /&gt;$processed.Add($group.DistinguishedName) | Out-Null&lt;br /&gt;&lt;br /&gt;function Get-Members ($group, $members, $processed) {&lt;br /&gt;    $group.members | ForEach-Object {&lt;br /&gt;        $group = $null&lt;br /&gt;        $group = Get-Group $_ -erroraction silentlycontinue&lt;br /&gt;        if ($group) {&lt;br /&gt;            if ($processed.add($group.DistinguishedName)) {&lt;br /&gt;                Get-Members -Group $group -Members $members -Processed $processed&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        else {&lt;br /&gt;            if ($members.add($_.DistinguishedName)) {&lt;br /&gt;                $_.DistinguishedName&lt;br /&gt;            } &lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;Get-Members -Group $group -Members $members -Processed $processed&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sysaddict.me/feeds/5600267655122725532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sysaddict.me/2013/12/how-to-get-distribution-group-members.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/5600267655122725532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/5600267655122725532'/><link rel='alternate' type='text/html' href='http://www.sysaddict.me/2013/12/how-to-get-distribution-group-members.html' title='How to get distribution group members recursively with powershell?'/><author><name>Frédéric Crespo</name><uri>https://plus.google.com/103200571988806930208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-5SUu2r0J2x0/AAAAAAAAAAI/AAAAAAAAAJM/sHCRJukYPxk/s512-c/photo.jpg'/></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1"/><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD"/></entry><entry><id>tag:blogger.com,1999:blog-1455897889336399878.post-7047499638734567854</id><published>2013-02-17T20:00:00.000+01:00</published><updated>2013-02-17T20:00:02.950+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DAPI"/><category scheme="http://www.blogger.com/atom/ns#" term="encryption"/><category scheme="http://www.blogger.com/atom/ns#" term="powershell"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><title type='text'>Securely storing passwords with Powershell</title><content type='html'>I just stumbled upon the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms995355.aspx&quot;&gt;Data Protection API&lt;/a&gt; from Microsoft that easily solves the problem of storing passwords and other sensitive data in scripts. It is really simple to use it from Powershell as can be seen below.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How to protect data?&lt;/h3&gt;&lt;div&gt;The snippet provided here accepts a string and a file name as input and will store the encrypted string into the &amp;nbsp;specified file.&lt;/div&gt;&lt;pre class=&quot;brush: ps&quot;&gt;Add-Type -assembly System.Security&lt;br /&gt;function New-Password($password, $file)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $plainText = [System.Text.Encoding]::Unicode.GetBytes($password)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $cipherText = [System.Security.Cryptography.ProtectedData]::Protect( $plainText, $null, &#39;CurrentUser&#39;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $cipherText | Set-Content -Encoding byte -Path $file&lt;br /&gt;}&lt;/pre&gt;&lt;h3&gt;&lt;/h3&gt;&lt;h3&gt;How to unprotect data?&lt;/h3&gt;&lt;div&gt;The function defined here takes the data from the file, decrypt it and transforms it back into a string. Simple enough!&lt;/div&gt;&lt;pre class=&quot;brush: ps&quot;&gt;Add-Type -assembly System.Security&lt;br /&gt;function Get-Password($file)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $cipherText = Get-Content -Encoding byte -Path $file&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $plainText = [System.Security.Cryptography.ProtectedData]::Unprotect($cipherText, $null, &#39;CurrentUser&#39;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $password = [System.Text.Encoding]::Unicode.GetString($plainText)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $password&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;You have no excuse anymore to store your password in clear text inside your scripts!</content><link rel='replies' type='application/atom+xml' href='http://www.sysaddict.me/feeds/7047499638734567854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sysaddict.me/2013/02/securely-storing-passwords-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/7047499638734567854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/7047499638734567854'/><link rel='alternate' type='text/html' href='http://www.sysaddict.me/2013/02/securely-storing-passwords-with.html' title='Securely storing passwords with Powershell'/><author><name>Frédéric Crespo</name><uri>https://plus.google.com/103200571988806930208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-5SUu2r0J2x0/AAAAAAAAAAI/AAAAAAAAAJM/sHCRJukYPxk/s512-c/photo.jpg'/></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1"/><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD"/></entry><entry><id>tag:blogger.com,1999:blog-1455897889336399878.post-8156799006127113937</id><published>2013-01-29T08:47:00.000+01:00</published><updated>2013-02-02T12:06:19.851+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term="DNS"/><category scheme="http://www.blogger.com/atom/ns#" term="powershell"/><title type='text'>Powershell: Leveraging the .NET framework</title><content type='html'>When I first started out writing powershell scripts I had a strong tendency to use my existing knowledge of Windows instead of using the power of the .NET framework that was available.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Command Line Way&lt;/h3&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;As an example lets look at name resolution. Let&#39;s suppose I am at a command prompt troubleshooting some kind of problems and my troubleshoot involves performing a DNS lookup. Most probably I will use nslookup to get the desired result.&lt;br /&gt;&lt;br /&gt;H:\&amp;gt;nslookup gmail.com&lt;br /&gt;Server:&amp;nbsp; anycast-fwd2-be.nw.shared.fortis&lt;br /&gt;Address:&amp;nbsp; 164.140.79.2&lt;br /&gt;Non-authoritative answer:&lt;br /&gt;Name:&amp;nbsp;&amp;nbsp;&amp;nbsp; gmail.com&lt;br /&gt;Addresses:&amp;nbsp; 173.194.34.150, 173.194.34.149&lt;br /&gt;&lt;br /&gt;NsLookup is a reliable tool I&#39;ve been using since I&#39;ve been working with computers. It never failed me. Now I am writing a simple script that needs to do a DNS lookup. Why not use nslookup here too? Powershell is still a shell and it will let me use any command line tool I&#39;m used to. It shouldn&#39;t then be too tricky to parse the answer?&lt;br /&gt;&lt;br /&gt;Since NSlookup is a command line tool I get a bunch of strings as a result of executing the tool from within Powershell. More precisely I get an array of Strings. Now I could go on&lt;br /&gt;and establish some kind of for loop that will iterate over each string and parse the string to get the answer. However this is where powershell becomes troublesome. Indeed altough is is used as a shell &lt;br /&gt;by administrators it does not easily befriend with command line tools IT administrators are used to.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;/h3&gt;&lt;h3&gt;The Powershell Way&lt;/h3&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Instead PowerShell likes the .NET Framework which is full of usefull classes. In this particular instance it seems like the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.net.dns.aspx&quot;&gt;DNS&lt;/a&gt;&amp;nbsp;class has everything we need to do a DNS lookup. In particular the GetHostAddresses (Returns the Internet Protocol (IP) addresses for the specified host) function seems about perfect. And instead of returning a bunch of strings to be parsed it will return a bunch of System.Net.IPAddress objects. Perfect!&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: ps&quot;&gt;$Name = &quot;NameOfTheMachine&lt;br /&gt;try { $dns = [System.Net.Dns]::GetHostAddresses($Name) }&lt;br /&gt;catch [System.Net.Sockets.SocketException]&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write-Host &quot;Host Unknown&quot;&lt;br /&gt;}&lt;br /&gt;catch&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write-Host &quot;A problem occured&quot;&lt;br /&gt;}&lt;br /&gt;Write-Host $dns&lt;br /&gt;&lt;/pre&gt;This is a lot easier than using the equivalent command line tool and it enables easy error checking. </content><link rel='replies' type='application/atom+xml' href='http://www.sysaddict.me/feeds/8156799006127113937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sysaddict.me/2013/01/powershell-leveraging-net-framework.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/8156799006127113937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/8156799006127113937'/><link rel='alternate' type='text/html' href='http://www.sysaddict.me/2013/01/powershell-leveraging-net-framework.html' title='Powershell: Leveraging the .NET framework'/><author><name>Frédéric Crespo</name><uri>https://plus.google.com/103200571988806930208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-5SUu2r0J2x0/AAAAAAAAAAI/AAAAAAAAAJM/sHCRJukYPxk/s512-c/photo.jpg'/></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1"/><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD"/></entry><entry><id>tag:blogger.com,1999:blog-1455897889336399878.post-8252760778657042491</id><published>2012-11-06T20:38:00.001+01:00</published><updated>2012-11-06T20:38:59.639+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Hyper-V"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows 8"/><title type='text'>Windows 8, Hyper-V and a USB disk</title><content type='html'>Since Hyper-V is now included in Windows 8 I decided to drop altogether using other Client Virtualization softwares such as VMware Workstation or Oracle VirtualBox for the time being and give Microsoft a chance.&lt;br /&gt;&lt;br /&gt;It turns out that Hyper-V is not yet very user friendly as a client side virtualization software. While setting up some machines I wanted to give them access to my external USB disk. As it turns out there is no setting anywhere that enables me to share my USB disk with a Hyper-V virtual machine on Windows 8.&lt;br /&gt;&lt;br /&gt;Instead I had to go to computer management and set the external disk as offline. This then enables me to add it to a virtual machine by adding another disk in the settings. Doing so requires the machine to be shutdown otherwise it would be to easy.&lt;br /&gt;&lt;br /&gt;As soon as I copied over a couple of files I needed to mount an iso file that was on that particular external disk. Again, Shutdown the virtual machine, remove the external disk from the settings of the machine, go to computer management, set the disk online, go to the virtual machine settings, select the DVD drive, select the iso you want to mount, boot the virtual machine, here you go!&lt;br /&gt;&lt;br /&gt;While this is not a show stopper and I&#39;ll probably keep using Hyper-V for now it is quite frustrating...</content><link rel='replies' type='application/atom+xml' href='http://www.sysaddict.me/feeds/8252760778657042491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sysaddict.me/2012/11/windows-8-hyper-v-and-usb-disk.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/8252760778657042491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/8252760778657042491'/><link rel='alternate' type='text/html' href='http://www.sysaddict.me/2012/11/windows-8-hyper-v-and-usb-disk.html' title='Windows 8, Hyper-V and a USB disk'/><author><name>Frédéric Crespo</name><uri>https://plus.google.com/103200571988806930208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-5SUu2r0J2x0/AAAAAAAAAAI/AAAAAAAAAJM/sHCRJukYPxk/s512-c/photo.jpg'/></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1"/><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD"/></entry><entry><id>tag:blogger.com,1999:blog-1455897889336399878.post-404903212353630622</id><published>2012-05-20T17:38:00.001+02:00</published><updated>2012-05-21T07:54:09.048+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term="powershell"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><title type='text'>How to transform a secure string into an unencrypted string?</title><content type='html'>If you&#39;ve been working with powershell you probably already know the &lt;i&gt;Get-Credential&lt;/i&gt; cmdlet. This cmdlet lets you prompt the user for his username and a password and stores that information into a&amp;nbsp;&lt;i&gt;System.Management.Automation.PSCredential &lt;/i&gt;object.&lt;br /&gt;&lt;br /&gt;Subsequently you can use the &lt;i&gt;PSCredential&lt;/i&gt; object any place you need a credential. Really, can you? Well actually not. Not so long a ago, I was writing a powershell script in an environment where WinRM (Powershell Remoting) was not supported and was playing around with a combination of&amp;nbsp;&lt;a href=&quot;http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx&quot;&gt;psexec&lt;/a&gt;&amp;nbsp;and &lt;i&gt;Get-WmiObject &lt;/i&gt;in order to get the job done&lt;i&gt;. The Get-WmiObject&lt;/i&gt; cmdlet accepts a &lt;i&gt;PSCredential&lt;/i&gt; object as a parameter so I could ask the user for his credentials and then starts querying wmi all around the place whith the supplied credentials. All was good. On the other hand &lt;i&gt;psexec&lt;/i&gt;&amp;nbsp;accepts two parameters regarding credentials. You can supply the username after the &lt;i&gt;-u&lt;/i&gt; switch and the password after the &lt;i&gt;-p&lt;/i&gt; switch. A username and a password can be retrieved from a &lt;i&gt;PSCredential&lt;/i&gt; object in the followinf way:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: ps&quot;&gt;$credential = Get-Credential&lt;br /&gt;&lt;br /&gt;Write-Host $credential.UserName #Retrieves the username&lt;br /&gt;Write-Host $credential.Password #Retrieves the password&lt;br /&gt;&lt;/pre&gt;This little snippet prompts the user for his credentials and then writes in the console the username and the password. However the password is written out as &quot;System.Security.SecureString&quot;. A&amp;nbsp;&lt;i&gt;System.Security.SecureString&lt;/i&gt; object stores an encrypted string instead of a plain string for security reasons. The SecureString has more features you can read about on &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.security.securestring.aspx&quot;&gt;msdn&lt;/a&gt;. Altough this is a much more secure way of storing sensitive information it cannot be passed along directly to programs like psexec which expects the password to be provided in clear text.&lt;br /&gt;&lt;br /&gt;In order to retrieve the password or the unencrypted string you&#39;ll need to use the&lt;i&gt; InteropServices&lt;/i&gt;. The below snippet realizes just that by allocating unmanaged memory space for the &lt;i&gt;SecureString&lt;/i&gt; with&amp;nbsp;&lt;i&gt;SecureStringToBSTR&lt;/i&gt;&amp;nbsp;and converting that unmanaged string back to a managed one with&amp;nbsp;&lt;i&gt;PtrToStringAuto&lt;/i&gt;. The end result is a standard .NET unencrypted string.&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: ps&quot;&gt;$pw = $credential.password&lt;br /&gt;$intPtr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw)&lt;br /&gt;$stringValue = [Runtime.InteropServices.Marshal]::PtrToStringAuto($intPtr)&lt;br /&gt;[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ptr)&lt;/pre&gt;&lt;br /&gt;I hope this can help you manage your code and leverage the Get-Credential cmdlet for all sort of use cases.</content><link rel='replies' type='application/atom+xml' href='http://www.sysaddict.me/feeds/404903212353630622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sysaddict.me/2012/05/how-to-get-string-behind-secure-string.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/404903212353630622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/404903212353630622'/><link rel='alternate' type='text/html' href='http://www.sysaddict.me/2012/05/how-to-get-string-behind-secure-string.html' title='How to transform a secure string into an unencrypted string?'/><author><name>Frédéric Crespo</name><uri>https://plus.google.com/103200571988806930208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-5SUu2r0J2x0/AAAAAAAAAAI/AAAAAAAAAJM/sHCRJukYPxk/s512-c/photo.jpg'/></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1"/><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD"/></entry><entry><id>tag:blogger.com,1999:blog-1455897889336399878.post-2765325596402320307</id><published>2011-10-29T19:16:00.000+02:00</published><updated>2011-10-30T22:32:33.262+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="powershell"/><title type='text'>Powershell: How to return an array from a function?</title><content type='html'>Today I discovered a neat little trick to return a multidimensional array from a Powershell function. While this should be an apaprently easy task it does not work the intuitive way. Indeed a .NET System.Array type implements the IEnumerable interface. When returning this object type from a function Powershell will enumerate it and store the enumerated data in a one dimensional array of objects. The Queue, ArrayList, SortedList, etc. types will behave the same way. All types that implement IEnumerable will.&lt;br /&gt;&lt;br /&gt;Look at the code snippet below. Intuitively I would think this code would return a two dimensional array of integers (System.Int32). However what is returned is a one dimensional array of objects.  &lt;br /&gt;&lt;pre class=&quot;brush: ps&quot;&gt;function Get-Array1 {&lt;br /&gt;    $table = New-Object &#39;int[,]&#39; 2,2&lt;br /&gt;    $table[0,0] = 0&lt;br /&gt;    $table[0,1] = 1&lt;br /&gt;    $table[1,0] = 2&lt;br /&gt;    $table[1,1] = 3&lt;br /&gt;    return $table&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;$res = Get-Array1&lt;br /&gt;Write-Host $res.gettype() # System.Object[]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So What is the trick to actually return the desired two dimensional array?&lt;br /&gt;&lt;br /&gt;First lets make sure we understand what Powershell does to our returned variable. Since the variable is of type IEnumerable then it will enumerate it and will return the objects inside the IEnumerable object. If there is only one object it will return that. If there are many it will return each of them inside an array of object.&lt;br /&gt;&lt;br /&gt;Since what we want is the multidimension array created inside the function we have to make sure it doesn&#39;t get enumerated but actually returned. The trick is to make our IEnumerable object the only member of another IEnumerable object. When returned the wrapper object gets enumerated and contains only one object (our multidimensional array) which is then returned.&lt;br /&gt;&lt;br /&gt;In the below snippet, the returned object is wrapped in a one dimensional array by preceding it with a comma.  &lt;br /&gt;&lt;pre class=&quot;brush: ps&quot;&gt;function Get-Array2 {&lt;br /&gt;    $table = New-Object &#39;int[,]&#39; 2,2&lt;br /&gt;    $table[0,0] = 0&lt;br /&gt;    $table[0,1] = 1&lt;br /&gt;    $table[1,0] = 2&lt;br /&gt;    $table[1,1] = 3&lt;br /&gt;    return ,$table&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;$res = Get-Array2&lt;br /&gt;Write-Host $res.gettype() # System.Int32[,]&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sysaddict.me/feeds/2765325596402320307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sysaddict.me/2011/10/powershell-how-to-return-array-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/2765325596402320307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/2765325596402320307'/><link rel='alternate' type='text/html' href='http://www.sysaddict.me/2011/10/powershell-how-to-return-array-from.html' title='Powershell: How to return an array from a function?'/><author><name>Frédéric Crespo</name><uri>https://plus.google.com/103200571988806930208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-5SUu2r0J2x0/AAAAAAAAAAI/AAAAAAAAAJM/sHCRJukYPxk/s512-c/photo.jpg'/></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1"/><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD"/></entry><entry><id>tag:blogger.com,1999:blog-1455897889336399878.post-4088595724395332004</id><published>2011-10-24T13:00:00.001+02:00</published><updated>2011-10-28T20:16:44.398+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="powershell"/><title type='text'>PowerShell Syntax HighLighting Test</title><content type='html'>This is a powershell syntax highlighting example:  &lt;pre class=&quot;brush: ps&quot;&gt;&lt;br /&gt;ForEach ($line in $file) {&lt;br /&gt;  Write-Host $line&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; I used the SyntaxHighlighter from Alex Gorbatchev that can be found at &lt;a href=&quot;http://alexgorbatchev.com/SyntaxHighlighter/&quot;&gt;http://alexgorbatchev.com/SyntaxHighLighter&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://www.sysaddict.me/feeds/4088595724395332004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sysaddict.me/2011/10/this-is-powershell-syntax-highlighting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/4088595724395332004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/4088595724395332004'/><link rel='alternate' type='text/html' href='http://www.sysaddict.me/2011/10/this-is-powershell-syntax-highlighting.html' title='PowerShell Syntax HighLighting Test'/><author><name>Frédéric Crespo</name><uri>https://plus.google.com/103200571988806930208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-5SUu2r0J2x0/AAAAAAAAAAI/AAAAAAAAAJM/sHCRJukYPxk/s512-c/photo.jpg'/></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1"/><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD"/></entry><entry><id>tag:blogger.com,1999:blog-1455897889336399878.post-1763079830046402020</id><published>2011-10-20T20:14:00.000+02:00</published><updated>2011-10-20T20:14:03.120+02:00</updated><title type='text'>Hello</title><content type='html'>Ok this is the first post and official start of this blog. Stay tuned for more interesting stuff to come regarding system administration and scripting in particular.</content><link rel='replies' type='application/atom+xml' href='http://www.sysaddict.me/feeds/1763079830046402020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sysaddict.me/2011/10/hello.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/1763079830046402020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1455897889336399878/posts/default/1763079830046402020'/><link rel='alternate' type='text/html' href='http://www.sysaddict.me/2011/10/hello.html' title='Hello'/><author><name>Frédéric Crespo</name><uri>https://plus.google.com/103200571988806930208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-5SUu2r0J2x0/AAAAAAAAAAI/AAAAAAAAAJM/sHCRJukYPxk/s512-c/photo.jpg'/></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1"/><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD"/></entry></feed>