tag:blogger.com,1999:blog-21601582367169805712024-03-12T18:08:33.476-07:00A Taste Of PowerShellShort posts about Microsoft PowerShell as I learn, trying to focus on one aspect at a time.Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.comBlogger62125tag:blogger.com,1999:blog-2160158236716980571.post-53972616288201519282012-01-25T09:56:00.000-08:002012-06-25T10:55:33.243-07:00Regular Expressions: Using Lookaheads to Group and Grab Exactly the Text You WantMy <a href="http://tasteofpowershell.blogspot.com/2012/01/named-groups-in-regular-expressions.html">previous post</a> used zero-width lookahead and lookbehind assertions to grab some text from a gnarly-looking string, so I thought I'd follow up with a quick post on how that works. It's not as complicated as the name sounds.<br />
<br />
I had this string, from which I wanted to extract the domain and username:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">\\SERVER\root\cimv2:Win32_Group.Domain="MYDOMAIN",Name="adminuser"</span><br />
<br />
I know that I want the text between the double-quotes immediately following the words "Domain" and "Name". I decided on this approach:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">$string -match '</span><span style="color: blue; font-family: 'Courier New', Courier, monospace;"><b>(?<=Domain\=")</b></span><span style="font-family: 'Courier New', Courier, monospace;">(</span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: red;">?<domain></span></b><span style="font-family: 'Courier New', Courier, monospace;">[^"]+).*</span><span style="color: blue; font-family: 'Courier New', Courier, monospace;"><b>(?<=Name\=")</b></span><span style="font-family: 'Courier New', Courier, monospace;">(</span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: red;">?<name></span></b><span style="font-family: 'Courier New', Courier, monospace;">[^"]+)'</span><br />
<br />
The characters in blue are, as described in the previous post, named groups, which will be captured and assigned in the automatic variable $matches with those names (Eg. $matches.domain). The characters in red are the zero-width lookbehind assertions.<br />
<div>
<br /></div>
<div>
So what are they good for? You can use lookaheads and lookbehinds if you want to make sure that a specific pattern comes before or after the pattern you want to capture, but <b>don't</b> actually want that pattern to be captured. They look like groups, but will not be added to $matches.</div>
<div>
<br /></div>
<div>
A lookbehind assertion looks like this:</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">(?<=YOUR_PATTERN_HERE)</span></div>
<div>
<br /></div>
<div>
A lookahead assertion looks like this:</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">(?=YOUR_PATTERN_HERE)</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: inherit;">Ah, but what if I want to make sure that a certain pattern does <b>not</b> follow my group? Just replace the equality sign with an exclamation point, like so:</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">(?<!YOUR_PATTERN_HERE)</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">(?!YOUR_PATTERN_HERE)</span></div>
<div>
<br /></div>
<div>
So let's break down what my regex does:</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"># Check that the pattern 'Domain\="' is in the string, </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"># but do not capture this group.</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">(?<=Domain\=") </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"># Immediately following it, capture one or more characters that are not the </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"># double-quote character </span><span style="font-family: 'Courier New', Courier, monospace;">and name this group "domain"</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">(?<domain>[^"]+)</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"># Match zero or more of any character.</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">.*</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"># Check that the pattern 'Name\="' is in the string, </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"># but do not capture this group.</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">(?<=Name\=")</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"># Immediately following it, capture one or more characters that are not the </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"># double-quote character </span><span style="font-family: 'Courier New', Courier, monospace;">and name this group "name"</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">(?<name>[^"]+)</span></div>
<div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-zWfWH2rHO4E/TyBCKdaj5xI/AAAAAAAAHkA/rYfi3TsuOjA/s1600/not_the_text.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-zWfWH2rHO4E/TyBCKdaj5xI/AAAAAAAAHkA/rYfi3TsuOjA/s1600/not_the_text.jpg" /></a></div>
<br /></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com5tag:blogger.com,1999:blog-2160158236716980571.post-23416515028807765442012-01-24T16:26:00.000-08:002012-01-24T16:41:57.579-08:00Named Groups in Regular ExpressionsI don't know how I went this long without discovering named groups in regular expressions, but I'm genuinely excited about them (yes, I'm a nerd).<br />
<br />
A quick recap of the most common way to use regular expressions in PowerShell. Let's say I have a string like the one below (sorry it isn't a more simple example, but this is literally something I ran into today). I got it by querying the local administrators of a system using SCCM. The problem is, I want it in domain\user format.<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">\\SERVER\root\cimv2:Win32_Group.Domain="MYDOMAIN",Name="adminuser"</span><br />
<br />
My first thought was to do something like this:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">$string -match '(?<=domain\=")([^"]+).*(?<=name\=")([^"]+)'</span><br />
<br />
It evaluates to <span style="font-family: 'Courier New', Courier, monospace;">True</span> on my test string, so I go look at <span style="font-family: 'Courier New', Courier, monospace;">$matches</span>:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">$matches</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Name Value</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">---- -----</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">2 adminuser</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">1 MYDOMAIN</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">0 MYDOMAIN",Name="adminuser</span><br />
<br />
Okay, I've captured my groups, but I notice something strange. Why is $matches a hashtable instead of an array? Because of named groups, that's why.<br />
<br />
To create a named group, you put the parentheses around it just like normal, but you add<br />
<span style="font-family: 'Courier New', Courier, monospace;">'?<groupname>'</span> to the beginning of the capture. This stores the group under the name 'groupname'. Let's try that with the above example:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">$string -match '(?<=domain\=")(<span style="color: red;"><b>?<domain></b></span>[^"]+).*(?<=name\=")(<b><span style="color: red;">?<name></span></b>[^"]+)'</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">$matches</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Name Value</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">---- -----</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">name adminuser</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">domain MYDOMAIN</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">0 MYDOMAIN",Name="adminuser</span><br />
<br />
It makes my regex a little longer, but it is so much easier now when I go to use the values I've collected to remember <span style="font-family: 'Courier New', Courier, monospace;">$matches.domain</span> and <span style="font-family: 'Courier New', Courier, monospace;">$matches.name</span> instead of <span style="font-family: 'Courier New', Courier, monospace;">$matches[1]</span> and <span style="font-family: 'Courier New', Courier, monospace;">$matches[2]</span>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-WWqBg5veElk/Tx9Km3nOOuI/AAAAAAAAHgE/c3-JPBE8xNs/s1600/love_regex.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="317" src="http://2.bp.blogspot.com/-WWqBg5veElk/Tx9Km3nOOuI/AAAAAAAAHgE/c3-JPBE8xNs/s320/love_regex.jpg" width="320" /></a></div>
<br />
<br />Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com3tag:blogger.com,1999:blog-2160158236716980571.post-63406491697432485222012-01-10T17:21:00.000-08:002012-01-10T17:29:21.288-08:00Harnessing the Power of PowerShell to Load-balance Sophos ServersAt work we have a decent-sized Sophos installation. This means that we have to use message relays to manage the status traffic back and forth between the Enterprise Console and the clients. I recently discovered that although I could use groups to point client updates to their local server for updating, the message routers weren't affected. As a result almost all clients ended up using the same server as a message relay. I confirmed with my TAM that this feature is by design, so I set out to fix it with a script. What I ended up with is basically what you see below.<br />
<br />
A few things worthy of note:<br />
<br />
<ul>
<li>I've pretty much standardized on using that logging boilerplate for most of my scripts. It makes it easy to log errors and insert debug statements at the code as I'm writing so that I can always set <span style="font-family: 'Courier New', Courier, monospace;">-loglevel</span> to '<span style="font-family: 'Courier New', Courier, monospace;">debug</span>' later when troubleshooting.</li>
<li>I made the caller pass the name of the <b>mrinit.conf</b> file so that I could create one small SCCM package for the script with all five different <b>mrinit.conf</b> files.</li>
<li>If you decide to do this, don't use the <b>mrinit.conf</b> file from the root of the package directory on the Update server. There should be an <b>mrinit.conf</b> file in the <b>rms </b>subfolder. Use that one. If it isn't there, then you might not be configured to use a message relay, and this script won't help you until you are.</li>
</ul>
<br />
<br />
<br />
<b><span style="color: red;">WARNING! ACHTUNG! AVISO! LUU Y!</span></b><br />
I am doing the QA and testing for my organization. I make no guarantees that this script will work for yours. Sophos is a temperamental beast, and you should do the due diligence to test and do the QA and do whatever modifications it takes to make it work for yours. You may also wish to consult with your Sophos TAM before undertaking a project like this.<br />
<br />
<br />
<script src="http://PoshCode.org/embed/3160" type="text/javascript">
</script>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-71308418431838369402011-10-05T18:39:00.000-07:002011-10-05T18:39:41.420-07:00InnerException: We have to go deeper.I helped a co-worker with an interesting issue today. He was writing a PowerShell script that downloads a file. He wanted to catch any errors with the download, so he had some code like this:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">$client = New-Object System.Net.WebClient</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">try {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> $client.DownloadFile('http://www/files/file.txt', file.txt)</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">catch [System.Net.WebException] {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> # $_ is set to the ErrorRecord of the exception</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> Out-Log $_.Exception.Message</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
This usually works, returning the text of the error, but this time he was getting back:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">An exception occurred during a WebClient request.</span><br />
<br />
That's not a very informative error. Removing the try/catch blocks, he got this on the screen:<br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">System.Net.WebException: An exception occurred during a WebClient request. ---> System.UnauthorizedAccessException: <span style="background-color: yellow;">Access to the path 'C:\</span></span><span style="background-color: yellow; font-family: 'Courier New', Courier, monospace;">Users\tojo2000\hosts.txt' is denied.</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean </span><br />
<span style="font-family: 'Courier New', Courier, monospace;">...</span><br />
<br />
<br />
So obviously the information is in there somewhere. It turns out that WebException usually returns the error code of the request, but if it runs into an error that is not related to the actual download, it will add the second exception to a property of the WebException object called InnerException. <br />
<br />
So the updated code looks something like this:<br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">$client = New-Object System.Net.WebClient</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">try {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> $client.DownloadFile('http://www/files/file.txt', file.txt)</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">catch [System.Net.WebException] {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> # $_ is set to the ErrorRecord of the exception</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> if ($_.Exception.InnerException) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> Out-Log $_.Exception.InnerException.Message</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> } else {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> Out-Log $_.Exception.Message</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: inherit;">Now we get the correct output:</span><br />
<span style="font-family: inherit;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Access to the path 'C:\Users\tojo2000\hosts.txt' is denied.</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com1tag:blogger.com,1999:blog-2160158236716980571.post-55804165400450259292011-07-15T19:17:00.000-07:002011-07-15T19:20:11.815-07:00When Is a String Not a String?I came across a really difficult-to-troubleshoot bug today, a real brain-teaser.<br />
<br />
A co-worker asked me to help him figure out why his PowerShell script was running a certain piece of code even though it shouldn't. He had a piece of code to detect a bad Windows Installer exit code like this:<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">$result = InstallSomeSoftware</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">if ($result -eq "1603") {</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> #do something...</span><br />
<br />
The "do something part was being executed no matter what value he returned from the <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">InstallSomeSoftware </span>function. To troubleshoot, he added some <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Write-Host</span> statements to display the return value on the screen before returning it inside the function. Sure enough, the expected value was printed on the screen, and it was <b>not</b> 1603.<br />
<br />
We both scratched our heads for a while, stepped through the function, and still weren't getting anywhere, when I noticed a few random lines of output. We realized that there were lines in his function that were returning values and not being captured by any variable or thrown away, so they were also being returned along with the expected value.<br />
<br />
So that leaves one last piece of the puzzle. Why would everything always evaluate to <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">True </span>when compared to the string "1603"? After a little more digging we had the answer. The first value being returned had the value <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">True</span>. <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> -eq</span>, when attempting to determine equality, saw that the two object types weren't the same, so it did what it was supposed to do: it cast the string "1603" as a System.Boolean and then checked to see if <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">True </span>was equal to <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">True </span>(which is what the string "1603" evaluates to as a Boolean).<br />
<br />
Many hairs were lost in this battle, but at least in the end we had our sanity.Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-86073734895357013092011-04-04T14:40:00.000-07:002011-04-04T14:40:47.220-07:00The 2011 Scripting Games Start Today!Just a reminder to get scripting. I'm going to try to make the time to participate in each event this year, and then I'll be posting my solutions here after the submissions are closed.<br />
<br />
If you're interested in the Scripting Games at all, I suggest you bookmark this URL: <a href="http://blogs.technet.com/b/heyscriptingguy/archive/2011/02/19/2011-scripting-games-all-links-on-one-page.aspx">All 2011 Scripting Games links on one page.</a>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com1tag:blogger.com,1999:blog-2160158236716980571.post-12699711910984561072011-03-03T18:37:00.000-08:002011-03-03T18:37:00.487-08:00One Approach to Logging in PowerShellI was writing a script recently, and I realized that I was missing the ability to use the standard logging module from Python. I decided to make a stripped-down logging function that would make logging easy, and that could be re-used. I'd be interested to hear what approaches others have taken to solving this problem. Here's what I came up with:<br />
<br />
<br />
<br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"># Set severity constants</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">$MSG_INFORMATION = 0</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">$MSG_WARNING = 1</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">$MSG_ERROR = 2</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">$MSG_SEVERITY = @(<span class="Apple-style-span" style="color: #38761d;">'Information'</span>, <span class="Apple-style-span" style="color: #38761d;">'Warning'</span>, <span class="Apple-style-span" style="color: #38761d;">'Error'</span>)</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"># Set configurable settings for logging</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">$LOG_LEVEL = $MSG_INFORMATION</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">$LOG_FILE = <span class="Apple-style-span" style="color: #38761d;">'my_logfile.log'</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">$SMTP_TO = <span class="Apple-style-span" style="color: #38761d;">'devnull@tojo2000.com'</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">$SMTP_SERVER = <span class="Apple-style-span" style="color: #38761d;">'smtp.tojo2000.com'</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">$SMTP_SUBJECT = <span class="Apple-style-span" style="color: #38761d;">'Script error!'</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">function Write-Log {</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> <span class="Apple-style-span" style="color: blue;"><#</span></span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> .SYNOPSIS</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> Writes a message to the Log.</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> .DESCRIPTION</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> Logs a message to the logfile if the severity is higher than $LOG_LEVEL.</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> .PARAMETER severity</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> The severity of the message. Can be Information, Warning, or Error.</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> Use the $MSG_XXXX constants.</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> Note that Error will halt the script and send an email.</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> .PARAMETER message</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> A string to be printed to the log.</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> .EXAMPLE</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> Log $MSG_ERROR "Something has gone terribly wrong!"</span><br />
<span class="Apple-style-span" style="color: blue; font-family: 'Courier New', Courier, monospace;"> #></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> param([Parameter(Mandatory=$true)][int]$severity,</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> [Parameter(Mandatory=$true)][string]$message)</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> if ($severity -ge $LOG_LEVEL) {</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> $timestamp = Get-Date -Format <span class="Apple-style-span" style="color: #38761d;">'yyyy-MM-dd hh:mm:ss'</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> $output = <span class="Apple-style-span" style="color: #38761d;">"$timestamp`t$($MSG_SEVERITY[$severity])`t$message"</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> Write-Output $output >> $LOG_FILE</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> if ($severity -ge $MSG_ERROR) {</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> Send-MailMessage -To $SMTP_TO `</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> -SmtpServer $SMTP_SERVER `</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> -Subject $SMTP_SUBJECT`</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> -Body $output `</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> -From $SMTP_FROM</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> exit 1</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">}</span>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-25485538194952927282011-01-25T18:56:00.000-08:002011-01-25T18:56:31.406-08:00Nothing To DO With PowerShellJust a quick update to plug one of my other projects: <a href="http://code.google.com/p/py-ad-ldap/">py-ad-ldap</a>. Have you ever wanted to run scripts against Active Directory but not wanted to run them on Windows? You haven't? Well, if you had, then this would have been the Python module for you. I haven't packaged it up for download yet (hopefully tomorrow), but it's pure Python, so there are no fancy requirements for installing it, so mosey on down to the repository and take a look at the source files if you're interested.Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-11387477980658033682011-01-23T12:53:00.000-08:002011-01-23T12:53:04.944-08:00Getting Performance Counters in PowerShellI had a friend ask me recently if there was an easy way to monitor arbitrary performance counters in a script, and I didn't really have time to think about it at the time, but this weekend I decided to give it a whirl, and I came up with this function, that I'll definitely be putting in my profile at work. <br />
<br />
The way it works is pretty straightforward, but you need to know some background about Performance Counters if you haven't used them before. There are basically four pieces of information needed to retrieve a counter:<br />
<br />
<ul><li>Category</li>
<li>Counter</li>
<li>Instance</li>
<li>Computer</li>
</ul><div>If these don't ring a bell right away, fire up Perfmon, right-click and select Add Counters, and you'll see something like this:</div><div><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_9mpXvVW8sBY/TTyTkN5NCII/AAAAAAAAAl8/zWEEHqP3pEE/s1600/perfmon.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="251" src="http://4.bp.blogspot.com/_9mpXvVW8sBY/TTyTkN5NCII/AAAAAAAAAl8/zWEEHqP3pEE/s320/perfmon.PNG" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: left;">In the top-left box you can see the Categories, and if you expand them you'll see the Counter names, and bottom left are the Instances.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">Classic example: you want to find out the Current Disk Queue Length on your C: drive.</div><div class="separator" style="clear: both; text-align: left;"></div><ul><li>Category = 'LogicalDisk'</li>
<li>Counter = 'Current Disk Queue Length'</li>
<li>Instance = 'C:'</li>
<li>Computer = '.' (default, it means "this computer")</li>
</ul><div>Using Get-PerformanceCounter, you'd do it like this:</div><div><br />
</div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Get-PerformanceCounter LogicalDisk 'C:' 'Current Disk Queue Length'</span></div><div><br />
</div><div>Or lets say you want to get all of the counters for the C: drive:</div><div><br />
</div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Get-PerformanceCounter LogicalDisk 'C:'</span></div><div><br />
</div><div><br />
</div><br />
<div>Anyway, here's the function, and you can also find it here: <a href="http://poshcode.org/2475">http://poshcode.org/2475</a></div><br />
<script src="http://PoshCode.org/embed/2475" type="text/javascript">
</script>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com1tag:blogger.com,1999:blog-2160158236716980571.post-68688332936029335452009-11-30T23:08:00.001-08:002009-11-30T23:11:03.903-08:00A Great Write-Up on WMI Events and PowerShell 2.0<span class="Apple-style-span" style="font-family:verdana;">I haven't been inspired to do a full post in a while, but I stumbled across this article by Trevor Sullivan today, and I thought I'd point it out for those of you that are interested.</span><div><span class="Apple-style-span" style="font-family:verdana;"><br /></span></div><div><span class="Apple-style-span" style="font-family:verdana;"><a href="http://trevorsullivan.wordpress.com/2009/11/16/powershell-getting-started-with-wmi-events/">PowerShell: Getting Started with WMI Events</a></span></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com2tag:blogger.com,1999:blog-2160158236716980571.post-67633017053826943102009-10-30T16:36:00.001-07:002009-10-30T17:33:46.424-07:00Working with CSV FilesIt's been a while since I had an update to the blog, and I've been waiting for something to jump out at me. Today I read on the news that the White House has released some visitor logs to the public, and they are making them<a href="http://www.whitehouse.gov/briefing-room/disclosures/visitor-records"> available for download</a> as a CSV file, and it piqued my interest, so I downloaded the file.<div><br /></div><div>PowerShell v1 and v2 both have a module called Import-CSV that makes it ridiculously easy to work with CSV files. They will slurp up the file and output an array of objects, one per row, with properties that correspond to the columns in the file.</div><div><br /></div><div>Let's import the file and look at a record:</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">PS> $visitors = Import-Csv .\10-30-waves-posting.csv</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">PS> $visitors[-1]</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">NAMELAST : ZIMPHER</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">NAMEFIRST : NANCY</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">NAMEMID : L</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">UIN : U81194</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">BDGNBR : 72400</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">ACCESS_TYPE : VA</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">TOA : 4/1/20091:45:42PM</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">POA : D0102</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">TOD : 4/1/20095:50:21PM</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">POD : D1</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">APPT_MADE_DATE : 3/25/20095:07:33PM</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">APPT_START_DATE : 4/1/20092:00:00PM</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">APPT_END_DATE : 4/1/200911:59:00PM</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">APPT_CANCEL_DATE :</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">Total_People : 3</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">LAST_UPDATEDBY : J7</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">POST : WIN</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">LastEntryDate : 3/25/20095:08:57PM</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">TERMINAL_SUFFIX : J7</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">visitee_namelast : DOUGLAS</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">visitee_namefirst : DEREK</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">MEETING_LOC : OEOB</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">MEETING_ROOM : 459</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">CALLER_NAME_LAST : WILKINS</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">CALLER_NAME_FIRST : ELIZABETH</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">CALLER_ROOM :</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">Description :</span></span></div><div><br /></div><div>Interesting. I wonder, who had the most visitors (I snipped out the middle of the results)?</div><div><br /></div><div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">PS> $visitors | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> Group-Object visitee_namelast | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> Sort-Object Count | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> Select-Object Count, Name</span></span></div><div><span class="Apple-style-span" style="color:#000066;"><br /></span></div><div><span class="Apple-style-span" style="color:#000066;"> Count Name</span></div><div><span class="Apple-style-span" style="color:#000066;"> ----- ----</span></div><div><span class="Apple-style-span" style="color:#000066;"> 1 ANDREW</span></div><div><span class="Apple-style-span" style="color:#000066;"> 1 LONG</span></div><div><span class="Apple-style-span" style="color:#000066;"> 1 BINNIX</span></div><div><span class="Apple-style-span" style="color:#000066;"> 1 BREWER</span></div><div><span class="Apple-style-span" style="color:#000066;"> ...</span></div><div><span class="Apple-style-span" style="color:#000066;"> 7 'SUMMERS'</span></div><div><span class="Apple-style-span" style="color:#000066;"> 7 JARRETT</span></div><div><span class="Apple-style-span" style="color:#000066;"> 8 'POTUS/FLOTUS'</span></div><div><span class="Apple-style-span" style="color:#000066;"> 8 'EMANUEL'</span></div><div><span class="Apple-style-span" style="color:#000066;"> 9 POTUS/FLOTUS</span></div><div><span class="Apple-style-span" style="color:#000066;"> 9 'DOEBLER'</span></div><div><span class="Apple-style-span" style="color:#000066;"> 10 DOEBLER</span></div><div><span class="Apple-style-span" style="color:#000066;"> 10 'TCHEN'</span></div><div><span class="Apple-style-span" style="color:#000066;"> 12 TCHEN</span></div><div><span class="Apple-style-span" style="color:#000066;"> 42 'POTUS'</span></div><div><span class="Apple-style-span" style="color:#000066;"> 56 POTUS</span></div><div><span class="Apple-style-span" style="color:#000066;"> 69 OFFICE</span></div><div><span class="Apple-style-span" style="color:#000066;"> 211</span></div></div><div><br /></div><div>Uh oh. There's something funky about this file. There are empty lines, and it's inconsistent about when it puts quotes around text fields. I'm pretty sure we don't have any fields with commas in them, so let's try stripping out any lines that only have whitespace and/or commas in them and then strip out single quotes from the rest of the lines:</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">PS> Get-Content .\10-30-waves-posting.csv | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> ?{$_ -notmatch '^(\s|,)*$'} | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> %{$_.replace("'", '')} > wh.csv</span></span></div><div><br /></div><div>** Note: that regex after -notmatch above can be read as:</div><div><span class="Apple-style-span" style="font-family:'courier new';"> ^ </span>start at the beginning of the string</div><div><span class="Apple-style-span" style="font-family:'courier new';"> (\s|,)* </span>zero or more whitespace or comma characters</div><div><span class="Apple-style-span" style="font-family:'courier new';"> $ </span>the end of the string</div><div><br /></div><div>There. Now we can try that again, using our new file (snipped for length again).</div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">PS> $visitors = Import-CSV .\wh.csv</span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';color:#000066;"><div>PS> $visitors |</div><div> Group-Object visitee_namelast |</div><div> Sort-Object Count |</div><div> Select-Object Count, Name</div></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> Count Name</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> ----- ----</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> 1 SHAH</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> 1 LONG</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> 1 PETER</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> 1 ANDREW</span></span></div><div><span class="Apple-style-span" style="font-family: 'courier new'; color: rgb(0, 0, 102); "> ...</span></div><div><span class="Apple-style-span" style="font-family: 'courier new'; color: rgb(0, 0, 102); "> 19 DOEBLER</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> 22 TCHEN</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> 69 OFFICE</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> 98 POTUS</span></span></div><div><br /></div><div>So now we know that the person with the largest number of visitors was the President of the United States of America. Hardly surprising, but you can easily explore this data with PowerShell. Here are a few more queries you might try:</div><div><br /></div><div>Look at the records of the visits to the President</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">PS> $visitors | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> ?{$_.visitee_namelast -eq 'POTUS'}</span></span></div><div><br /></div><div>How many visits occurred in July?</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">PS> $visitors | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> ?{$_.APPT_START_DATE -match '^7/'} | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> sort APPT_START_DATE | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> select NAMELAST, NAMEFIRST, APPT_START_DATE</span></span></div><div><br /></div><div>What was the description given of the appointments for meeting the President?</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;">PS> $visitors | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> ?{$_.visitee_namelast -eq 'POTUS'} | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> select APPT_START_DATE, NAMEFIRST, NAMELAST, Description | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"> sort APPT_START_DATE</span></span></div></div></div></div><div><br /></div><div><br /></div><div>Hopefully this gives you a good idea of how you can manipulate CSV data using PowerShell using Import-CSV and a little filtering.</div></div></div></div><div><br /></div></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-6427847577096117252009-09-03T14:17:00.000-07:002009-09-17T18:26:12.604-07:00A Regular Expression Cheat Sheet for PowerShellOkay, so there's really not much that is PowerShell-specific about this cheat sheet, but I wrote it up in response to a post on <a href="http://groups.google.com/group/microsoft.public.windows.powershell/topics">microsoft.public.windows.powershell</a>, and I thought I'd share it here, since I know a lot of new PowerShell users haven't been exposed to Regular Expressions very much. <div><br /></div><div>This is not meant as an exhaustive reference on regular expressions, but just something that may be helpful if you get a little stuck. I hope you find it helpful.</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><u><b>1. What kind of character is it?</b></u></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>[]</b> - any of the characters inside the brackets will match</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> (use the dash to indicate a range)</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> <i>Examples:</i> <i>[a-z] will match any letter.</i></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> <i>[aeiou] will match any vowel</i></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>\w</b> - "word" characters. Basically matches [a-z0-9_]</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>\s</b> - "whitespace" characters. matches spaces, tabs, etc.</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>\d</b> - any digit. Basically matches [0-9]</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>\t</b> - a tab character</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>.</b> - any character</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><u><b>2. How many characters? </b></u></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> (the below appear after the character class)</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>{x}</b> - matches x number of characters</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>{x, y}</b> - matches minimum x number of characters, maximum y characters</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> <i>Examples: \d{4} matches 4 digits</i></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>*</b> - matches ZERO or more of the character (as many as possible)</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>+</b> - matches ONE or more of the character (as many as possible)</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>*?</b> - matches ZERO or more characters (as few as possible)</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>+?</b> - matches ONE or more characters (as few as possible)</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><u><b>3. Where is the character?</b></u></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>\b</b> - matches a word boundary, without actually absorbing any characters</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>^</b> - matches the beginning of a string</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>$</b> - matches the end of a string</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><u><b>4. Grouping</b></u></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>()</b> - any characters between the parentheses will be their own group</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> (try checking the value of $matches after using -match)</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><b>|</b> - a pipe character is the OR character</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><i> Example: (one|two) will match the word "one" or the word "two"</i></span></div></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com3tag:blogger.com,1999:blog-2160158236716980571.post-23796122950725841622009-08-26T15:08:00.000-07:002009-08-26T15:17:20.705-07:00Add a List of Users to the Local Admins GroupJust a quick update here, and another real-world example of where the Split() method of a string can come in handy for day-to-day tasks.<div><br /></div><div>Today I had to add a list of about 20 individual usernames as administrators to a particular machine. Someone sent me the comma-separated list in an IM, and it took me about ten seconds:</div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;">PS> 'user1,user2,user3,user4,user5,user6,user7,user8,user9,user10'.split(',') | </span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;">>> %{net localgroup administrators $_ /add}</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><div><span class="Apple-style-span" style="font-family: 'courier new'; font-size: small; ">The command completed successfully.</span></div><div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;">The command completed successfully.</span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;">The command completed successfully.</span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;">The command completed successfully.</span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;">The command completed successfully.</span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;">The command completed successfully.</span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;">The command completed successfully.</span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;">The command completed successfully.</span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;">The command completed successfully.</span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="font-size: small;">The command completed successfully.</span></span></div></div></div></div></div></div></div></div></div></div></div></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-26254551231042290262009-08-12T21:36:00.000-07:002009-08-12T21:51:16.226-07:00Use PowerShell to Get Local Group Members from a Remote ComputerI had a friend ask me recently how to get a list of administrators from a server.<div><br /></div><div>"That's easy" I thought. "You just have to... um... actually..."</div><div><br /></div><div>It turns out that this can be frustratingly difficult in PowerShell, so I wrote this module to make it easier when I'll need to do this in the future. It's comprised of three functions:</div><div><ul><li><span class="Apple-style-span" style="font-family:'courier new';"><b>Add-NoteProperty</b></span>: About 90% of the time when I want to create a custom PSObject and add some properties, they're all NoteProperties. This function makes adding a property easy, like so: <span class="Apple-style-span" style="font-family:'courier new';">Add-NoteProperty $my_object 'PropertyName' $property</span></li><li><span class="Apple-style-span" style="font-family:'courier new';"><b>Get-COMProperty</b></span>: This is a kludgy hack to get around the fact that members of groups gotten through ADSI get returned as __ComObject objects, and you have to call the InvokeMember() static method of the class in order to get at their properties. Now I can just do this: <span class="Apple-style-span" style="font-family:'courier new';">Get-COMProperty $com_object 'PropertyName'</span></li><li><b><span class="Apple-style-span" style="font-family:'courier new';">Get-LocalGroups</span></b>: This is the function that we needed. It returns a list of custom PSObjects representing the local groups on a server, and each one has a property called Members that is a list of custom PSObjects for each member, including the Name, Domain, and ADSPath. From there, you can use whatever method you want to the object you want, whether it's using Get-QADUser for domain users, or whatever, for example: <span class="Apple-style-span" style="font-family:'courier new';">Get-LocalGroups computername</span>.</li></ul><div>If you're using Powershell v2 CTP3 or higher, you can use help on each of the functions to see examples if you forget. You can download the module from Poshcode.org <a href="http://poshcode.org/1268">here</a>.</div><div><br /></div><div><br /><script type="text/javascript" src="http://PoshCode.org/embed/1268"></script><br /></div></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com1tag:blogger.com,1999:blog-2160158236716980571.post-69282550790177904652009-08-08T15:32:00.001-07:002009-08-08T17:11:27.412-07:00String Manipulation: Splitting and Joining StringsI think it's time to get back to some more basic things, so let's get to it.<div><br /></div><div>The <span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>split()</b></span></span>method of a string object lets you define a delimiter and "split" the string up into multiple pieces, which are returned as an array. </div><div><br /></div><div>Let's say I do this:</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>PS C:\Users\tojo2000> $string = "one two three four"</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>PS C:\Users\tojo2000> $string.split(" ")</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>one</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>two</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>three</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>four</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new', serif;color:#000066;"><b><br /></b></span></div><div><br /></div><div>As it turns out, though, split() splits on a single whitespace character by default.</div><div><br /></div><div>Observe:</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>PS C:\Users\tojo2000> $string = "one two three four six"</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>PS C:\Users\tojo2000> $string.split()</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>one</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>two</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>three</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>four</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b><br /></b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>six</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new', serif;color:#000066;"><b><br /></b></span></div><div><br /></div><div>What's the practical use for this? Let's say you have a tab-separated values file called people.txt that looks like this:</div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Doe</b></span></span><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>John</b></span></span><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>California</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Doe</b></span></span><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Jane</b></span></span><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Texas</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Neuman</b></span></span><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Alfred</b></span></span><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Nebraska</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new', serif;color:#000066;"><b><br /></b></span></div><div><br /></div><div>And you want the output to be First Last, Location. You could do it like so:</div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>PS C:\Users\tojo2000> Get-Content people.txt | </b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>>> %{$data = $_.split("`t"); Write-Output "$($data[1]) $($data[0]), $($data[2])"}</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>>></b></span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>John Doe, California</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Jane Doe, Texas</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Alfred Neuman, Nebraska</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new', serif;color:#000066;"><b><br /></b></span></div></div><div><br /></div><div>But what if you have a file like this called people2.txt (let's say the first part is some kind of ID)?</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>2323:Doe</b></span></span><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>John</b></span></span><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>California</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>827:Doe</b></span></span><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Jane</b></span></span><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Texas</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>982982:Neuman</b></span></span><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Alfred</b></span></span><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b> </b></span></span></span><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Nebraska</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new', serif;color:#000066;"><b><br /></b></span></div><div><br /></div><div>Now you have two delimiters, but the split() method of a string object takes a string as an argument, so you would have to split twice in order to get each part of the string split into an array. If only there was some way to split on a regular expression... Oh, wait, there is.</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>PS C:\Users\tojo2000> Get-Content people2.txt | </b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>>> %{$data = [regex]::split($_, '\t|:'); Write-Output "$($data[2]) $($data[1]), $($data[3])"}</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>>></b></span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>John Doe, California</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Jane Doe, Texas</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>Alfred Neuman, Nebraska</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new', serif;color:#000066;"><b><br /></b></span></div><div><br /></div><div>('\t|:' is a regular expression for a tab character or a colon)</div><div><br /></div><div>What if you have an array, and you want to make a string out of it? Then you can join the strings together using join(). Now there are two ways to join a list of strings, depending on whether you're using PowerShell v1 or v2. </div><div><br /></div><div>The first way works in both v1 and v2:</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>PS C:\Users\tojo2000> $buncha_strings = 'one', 'two', 'three', 'four', 'five', 'six'</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>PS C:\Users\tojo2000> [string]::join(' and a ', $buncha_strings)</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>one and a two and a three and a four and a five and a six</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new', serif;color:#000066;"><b><br /></b></span></div></div><div><br /></div><div>So what practical use would there be? For a completely contrived example, maybe you want to create a new version of people2.txt called people3.txt that uses pipe characters to separate the fields. We'll split the strings up into an array just like before, but then we'll join them back together the way we want them.</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>PS C:\Users\tojo2000> Get-Content people2.txt | </b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>>> %{$data = [regex]::split($_, '\t|:'); [string]::join('|', $data)} > people3.txt</b></span></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>PS C:\Users\tjo2000> Get-Content .\people3.txt</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>2323|Doe|John|California</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>827|Doe|Jane|Texas</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>982982|Neuman|Alfred|Nebraska</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new', serif;color:#000066;"><b><br /></b></span></div><div><br /></div><div>There is one more way that you can join a list of strings, but this method only works in v2: the -join operator. It works the same way as the other <span class="Apple-style-span" style="font-family:'courier new';"><b><span class="Apple-style-span" style="color:#000066;">join()</span></b></span>, but the syntax is slightly different. </div><div><br /></div><div>For example, here is how you would join a list of strings by tab characters:</div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>PS C:\Users\tojo2000> $list_of_strings -join "`t"</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new', serif;color:#000066;"><b><br /></b></span></div><div><br /></div><div>So to wrap this all up, let me give a real-world example. I had a SQL query that I wanted to run that would retrieve the SCCM information for a specific list of computers. I needed to update the list, and I had the computers in a file called machines.txt, with one name per line. </div><div><br /></div><div>Here's how I slurped up the file to create the new query string:</div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>$query = @"</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>SELECT * FROM v_R_System </b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>WHERE Netbios_Name0 </b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>IN ('{0}')</b></span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#000066;"><b>"@ -f ((Get-Content machines.txt) -join "', '")</b></span></span></div></div></div></div></div></div></div></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com7tag:blogger.com,1999:blog-2160158236716980571.post-51098297682529460242009-07-04T02:29:00.000-07:002009-07-04T03:00:59.221-07:00Super Duper Over-Engineered Egg Timer<div style="text-align: center;"><br /></div>This was my submission for Event 10 Beginner of the 2009 Scripting Games this year. I used<a href="http://www.primaltools.com/downloads/communitytools/">PrimalForms</a> to design the form and generate the boilerplate code. It's a really great tool.<div><br /></div><div>I added the timer functionality myself. The <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.timer_members.aspx">Windows.Forms.Timer</a> object is very simple. You tell it how frequent to set the ticks, set it to enabled or disabled, and call Start() to kick it off. The Timer itself doesn't keep track of how long it has been going, you do that by adding an event handler for the Tick event. You do that as seen on line 5 below, by calling add_tick() on the Timer object and passing it a script block that will be called every time the event fires. As far as I can tell this should work for any Windows.Forms object, calling add_event(), where "event" is the name of the event you are adding a handler for. The interval is in miliseconds, so in this case</div><div> the scriptblock $timer1_OnTick will be called once every second.</div><div><br /></div><div>I went ahead and gathered the relevant lines in one place below so it's easier to see what I did. They're kind of spread around in <a href="http://poshcode.org/1192">the actual script</a>.</div><div><br /></div><div><ol><li><span class="Apple-style-span" style=" line-height: 10px; font-family:monospace, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:13px;"><span class="re3" style="color: rgb(102, 0, 51); font-weight: bold; "><span class="Apple-style-span" style="font-size:large;">$timer1</span></span><span class="Apple-style-span" style="font-size:large;"> </span><span class="sy0" style="color: rgb(102, 204, 102); "><span class="Apple-style-span" style="font-size:large;">=</span></span><span class="Apple-style-span" style="font-size:large;"> </span><span class="re0" style="color: rgb(0, 102, 204); font-style: italic; "><span class="Apple-style-span" style="font-size:large;">New-</span><span class="re1" style="font-style: normal; "><span class="Apple-style-span" style="font-size:large;">Object</span></span></span><span class="Apple-style-span" style="font-size:large;"> </span><span class="kw3" style="color: rgb(0, 51, 102); font-weight: bold; "><span class="Apple-style-span" style="font-size:large;">System</span></span><span class="Apple-style-span" style="font-size:large;">.</span><span class="me1" style="color: rgb(0, 51, 102); "><span class="Apple-style-span" style="font-size:large;">Windows</span></span><span class="Apple-style-span" style="font-size:large;">.</span><span class="me1" style="color: rgb(0, 51, 102); "><span class="Apple-style-span" style="font-size:large;">Forms</span></span><span class="Apple-style-span" style="font-size:large;">.</span><span class="me1" style="color: rgb(0, 51, 102); "><span class="Apple-style-span" style="font-size:large;">Timer</span></span></span></li><li><span class="Apple-style-span" style=" line-height: 10px; font-family:monospace, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:13px;"><span class="re3" style="color: rgb(102, 0, 51); font-weight: bold; "><span class="Apple-style-span" style="font-size:medium;">$timer1</span></span><span class="Apple-style-span" style="font-size:medium;">.</span><span class="me1" style="color: rgb(0, 51, 102); "><span class="Apple-style-span" style="font-size:medium;">Enabled</span></span><span class="Apple-style-span" style="font-size:medium;"> </span><span class="sy0" style="color: rgb(102, 204, 102); "><span class="Apple-style-span" style="font-size:medium;">=</span></span><span class="Apple-style-span" style="font-size:medium;"> </span><span class="re3" style="color: rgb(102, 0, 51); font-weight: bold; "><span class="Apple-style-span" style="font-size:medium;">$true</span></span></span></li><li><span class="Apple-style-span" style=" line-height: 10px; font-family:monospace, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:13px;"><span class="re3" style="color: rgb(102, 0, 51); font-weight: bold; "><span class="Apple-style-span" style="font-size:medium;">$timer1</span></span><span class="Apple-style-span" style="font-size:medium;">.</span><span class="kw4" style="color: rgb(102, 0, 51); "><span class="Apple-style-span" style="font-size:medium;">Start</span></span><span class="br0" style="color: rgb(51, 51, 51); "><span class="Apple-style-span" style="font-size:medium;">(</span></span><span class="br0" style="color: rgb(51, 51, 51); "><span class="Apple-style-span" style="font-size:medium;">)</span></span></span></li><li><span class="Apple-style-span" style=" line-height: 10px; font-family:monospace, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:13px;"><span class="re3" style="color: rgb(102, 0, 51); font-weight: bold; "><span class="Apple-style-span" style="font-size:large;">$timer1</span></span><span class="Apple-style-span" style="font-size:large;">.</span><span class="me1" style="color: rgb(0, 51, 102); "><span class="Apple-style-span" style="font-size:large;">Interval</span></span><span class="Apple-style-span" style="font-size:large;"> </span><span class="sy0" style="color: rgb(102, 204, 102); "><span class="Apple-style-span" style="font-size:large;">=</span></span><span class="Apple-style-span" style="font-size:large;"> </span><span class="nu0" style="color: rgb(204, 102, 204); "><span class="Apple-style-span" style="font-size:large;">1000</span></span></span></li><li><span class="Apple-style-span" style=" line-height: 10px; font-family:monospace, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:13px;"><span class="re3" style="color: rgb(102, 0, 51); font-weight: bold; "><span class="Apple-style-span" style="font-size:large;">$timer1</span></span><span class="Apple-style-span" style="font-size:large;">.</span><span class="me1" style="color: rgb(0, 51, 102); "><span class="Apple-style-span" style="font-size:large;">add_tick</span></span><span class="br0" style="color: rgb(51, 51, 51); "><span class="Apple-style-span" style="font-size:large;">(</span></span><span class="re3" style="color: rgb(102, 0, 51); font-weight: bold; "><span class="Apple-style-span" style="font-size:large;">$timer1_OnTick</span></span><span class="br0" style="color: rgb(51, 51, 51); "><span class="Apple-style-span" style="font-size:large;">)</span></span></span></li></ol></div><div><span class="Apple-style-span" style="font-family:monospace, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:100%;color:#333333;"><span class="Apple-style-span" style=" line-height: 10px;font-size:13px;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:monospace, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:100%;color:#333333;"><span class="Apple-style-span" style=" line-height: 10px;font-size:13px;"><img src="http://2.bp.blogspot.com/_9mpXvVW8sBY/Sk8ngkpGDwI/AAAAAAAAAeI/spwbtNAHIVs/s400/egg_timer.png" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 188px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5354541922512146178" /></span></span></div><div><span class="Apple-style-span" style="font-family:monospace, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:100%;color:#333333;"><span class="Apple-style-span" style=" line-height: 10px;font-size:13px;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:monospace, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:100%;color:#333333;"><span class="Apple-style-span" style=" line-height: 10px;font-size:13px;"><br /></span></span></div><div><span class="Apple-style-span" style="font-family:monospace, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:100%;color:#333333;"><span class="Apple-style-span" style=" line-height: 10px;font-size:13px;"><br /></span></span></div><script type="text/javascript" src="http://PoshCode.org/embed/1192"></script><div></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-62643507400623977552009-06-30T13:29:00.000-07:002009-06-30T13:36:52.280-07:00Recursively Getting All Folder SizesThis started out as my entry for Event 8 in the <a href="http://blogs.technet.com/heyscriptingguy/archive/2009/06/14/everything-scripting-games-come-here-if-you-are-lost.aspx">Microsoft Scripting Games 2009</a> (see more entries <a href="http://scriptinggames.poshcode.org/">here</a>), but it's useful, so I think I'll keep it. This function uses recursion to work its way down the directory tree and get all folders and their sizes, and outputs them as psobjects for easy sorting, etc. It's not the fastest thing in the world, but it does the trick. Make sure to check out the examples in the help documentation.<div><br /></div><div><br /><div><br /></div><div><br /><script type="text/javascript" src="http://PoshCode.org/embed/1185"></script><br /></div></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-53200204605206483502009-06-09T12:33:00.001-07:002009-06-09T13:41:53.982-07:00The 2009 Scripting Games!So the <a href="http://blogs.technet.com/heyscriptingguy/archive/2009/05/28/details-leaked-about-the-2009-summer-scripting-games.aspx">2009 Scripting Games</a> have begun! There are 10 events this year, and the theme is decathalon. This is my first year participating. The next few posts will be my solutions. Check out the <a href="http://www.microsoft.com/technet/scriptcenter/default.mspx">Script Center</a> for updates and event details.Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-43449199354623505212009-05-31T20:20:00.000-07:002009-05-31T20:52:49.615-07:00Using Strict Mode with Set-PSDebugIf you've used Perl in the past, then you're probably familiar with "<span class="Apple-style-span" style="font-family:'courier new';">use strict</span>" (if you've been using Perl without "<span class="Apple-style-span" style="font-family:'courier new';">use strict</span>", then <a href="http://www.perlmonks.org/?node_id=111088">head over here</a> Note: the scoping issues don't apply to PowerShell).<div><br /></div><div>By default, PowerShell is very accommodating. If you tell it to echo the value of <span class="Apple-style-span" style="font-family:'courier new';">$chouderhead</span>, it will happily echo... NOTHING! There is no variable called <span class="Apple-style-span" style="font-family:'courier new';">$chouderhead</span>, you misspelled <span class="Apple-style-span" style="font-family:'courier new';">$chowderhead</span>. PowerShell doesn't like to make waves, though, so it happily creates a new variable named <span class="Apple-style-span" style="font-family:'courier new';">$chouderhead</span> and starts using it. This can lead to very hard-to-debug issues.</div><div><br /></div><div>You can fix this By adding this line to your profile (or just typing it in at the prompt):</div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';">PS> Set-PSDebug -strict</span></div><div><br /></div><div>Now if you try to use a variable that hasn't yet had a value assigned to it, you'll get an error like this:</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';">PS> $chouderhead</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#FF0000;">The variable '$chouderhead' cannot be retrieved because it has not been set.</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#FF0000;">At line:1 char:13</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#FF0000;">+ $chouderhead <<<<</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#FF0000;"> + CategoryInfo : InvalidOperation: (chouderhead:Token) [], RuntimeException</span></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#FF0000;"> + FullyQualifiedErrorId : VariableIsUndefined</span></span></div><div><br /></div><div>The error is annoying, but if you've ever wasted a half an hour wondering why your script isn't outputting what you thought it would, only to realize that on line 304 you accidentally used an 'm' instead of an 'n' in your variable name and how could I miss that, it's so stupid, and now I missed dinner, and my back hurts from crouching over my keyboard staring at the screen for too long and curse the day I was born! Why, oh, why didn't I just add 'PSDebug -strict' to my profile? Why? </div><div><br /></div><div>But I digress...</div></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-41901921830222406452009-05-19T13:32:00.000-07:002009-05-20T11:03:29.504-07:00Get-ChildItemRecurse Update<div>Someone named CrazyDave made an important update to the script I made yesterday. I was checking for the specific type System.IO.DirectoryInfo. The problem with this is, it unnecessarily limits my script to being used on files and folders. Get-ChildItem makes no such distinction. It can be used on any PSDrive.</div><div><br /></div><div>So here is the corrected version: <a href="http://poshcode.org/1115">http://poshcode.org/1115</a> (highlighted line is the old one)</div><div><br /></div><div><br /><script type="text/javascript" src="http://PoshCode.org/embed/1115"></script><br /></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-30094061473374275202009-05-18T22:30:00.000-07:002009-05-18T22:38:33.558-07:00A Get-ChildItem Wrapper That Lets You Say How Deep to RecurseI noticed that a couple of people hit my blog that seemed to be looking for a script like this, and it turned out to be an interesting exercise. <div><br /></div><div>Notice that I took the fileglob and moved it down the script rather than just using it in my call to Get-ChildItem. I had to do that because otherwise I would only have been recursing through directories that matched the pattern, and I wanted to recurse down into all directories, but only send those entries that match the pattern down the pipeline.</div><div><br /></div><div>The function is here, for those that don't see it inline in the post: <a href="http://poshcode.org/1113">http://poshcode.org/1113</a></div><div><br /></div><div><br /><script type="text/javascript" src="http://PoshCode.org/embed/1113"></script><br /></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com1tag:blogger.com,1999:blog-2160158236716980571.post-60243501779182485082009-05-03T22:59:00.001-07:002009-05-03T23:11:08.823-07:00Use PowerShell to Recursively Get Group MembersI've noticed looking at my StatCounter logs that a few people found <a href="http://tasteofpowershell.blogspot.com/2008/08/recursion-in-powershell.html">my post on recursion</a> while looking for a way to recursively get group members in PowerShell, so I whipped up <a href="http://poshcode.org/1077">this script</a>.<div><br /></div><div>Note that it depends on the <a href="http://www.quest.com/powershell/activeroles-server.aspx">AD Cmdlets from Quest</a>, and that it works in much the same way as the example. Whenever it finds that one of the group members is a group, it calls itself on that group and adds the result to the list of users.</div><div><br /></div><div>Also note the technique of using a hashtable to keep a list of unique users. It's common to store a list in an array and use use -contains and -notcontains to find out if an item already exists, but this is tremendously inefficient compared to using a hashtable as an index, especially as the list of users gets longer, because it has to keep cycling through the list over and over. It's a trick I picked up in Perl that works equally well here.</div><div><br /></div><div><br /><script type="text/javascript" src="http://PoshCode.org/embed/1077"></script><br /></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com3tag:blogger.com,1999:blog-2160158236716980571.post-31408781286562904912009-05-02T22:44:00.000-07:002009-05-02T22:56:11.445-07:00An Excellent Post on Bitwise OperatorsIf you find yourself working with Microsoft APIs for any length of time, you'll find yourself having to deal with bitmasks and bitwise operations. Mark Schill over at <a href="http://www.cmschill.net/stringtheory/">String Theory</a> has an excellent description of what they are and how to work with them.<div><br /></div><div><span class="Apple-style-span" style="font-size:large;"><b><a href="http://www.cmschill.net/stringtheory/2009/05/02/bitwise-operators/">Bitwise Operators</a></b></span></div><div><b><br /></b></div><div><b><br /></b></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-67626625844606659812009-05-01T16:47:00.000-07:002009-05-01T18:06:53.359-07:00Advanced Functions: Using Values from the Pipeline (2.0 CTP3)<i>Note: The following code will only work on </i><a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=c913aeab-d7b4-4bb1-a958-ee6d7fe307bc"><i>Powershell 2.0 CTP3</i></a><i> or later.</i><div><br /></div><div>A while back I showed how you can use $input as a parameter to a function in order to use it in the pipeline. Unfortunately that technique has the side effect of making PowerShell stop and gather up all variables that are being sent down the pipeline into $Input and then passing it to the function. Ordinarily it doesn't matter much, but if you are processing a lot of data, say the results of a SQL query, you may end up using up massive amounts of memory and watch your computer grind to a halt while the memory manager swaps a billion times a second (okay, I made that number up).</div><div><br /></div><div><b><span class="Apple-style-span" style="font-size:large;"><span class="Apple-style-span" style="font-family:verdana;">The ValueFromPipeline Parameter Property</span></span></b></div><div><br /></div><div>As the name suggests, this property indicates whether or not a parameter can take a value from the pipeline. Just set it to $true when declaring the variable (you'll see an example at the bottom of this post). </div><div><br /></div><div>Doing that alone will not give you the effect you're looking for, though. It will mysteriously process the first item passed down the pipeline...and then suddenly stop. This was very frustrating when I first came across it, and left me scratching my head, until a post on the <a href="http://groups.google.com/group/microsoft.public.windows.powershell/topics">microsoft.public.windows.powershell</a> group happened to mention the critical missing piece in an unrelated discussion.</div><div><br /></div><div><br /></div><div><div><span class="Apple-style-span" style="font-size:large;"><b><span class="Apple-style-span" style="font-family:verdana;">BEGIN, END, and PROCESS Blocks</span></b></span></div><div><br /></div><div>The first thing you need to know is that if you want to take a value from the pipeline and use it, then you need to add in the optional PROCESS Block. Every function essentially has a BEGIN, END, and PROCESS scriptblock in it:</div><div><ul><li>BEGIN - This scriptblock is run the first time the function is launched</li><li>PROCESS - This scriptblock is run each time the function receives input</li><li>END - This scriptblock is run after all input has been processed</li></ul></div><div>Here's the important part: explicitly declaring these blocks is optional, but if you don't use them, then the body of your function executes in the END Block. That's why it was only executing once.</div><div><br /></div></div><div>As an example of a script that uses these blocks, take a look at <a href="http://poshcode.org/1072">this little ditty</a> I whipped up for work (I highlighted the important parts):</div><div><br /></div><div><br /><script type="text/javascript" src="http://PoshCode.org/embed/1072"></script><br /></div><div><br /></div>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0tag:blogger.com,1999:blog-2160158236716980571.post-64394822954827440342009-03-31T00:48:00.000-07:002009-03-31T01:16:18.623-07:00SMS Module UpdatedI updated the SMS Module (<a href="http://tasteofpowershell.blogspot.com/2008/10/get-smswmi-and-find-smsid.html">old post here</a>) for PowerShell v2. I'm using it with v2 CTP3. Now you can type "<span class="Apple-style-span" style="font-family:'courier new';">help <function></function></span>" to get help on these functions, and check out the old post for more examples of how you can use the Get-SmsWmi and Find-SmsId functions.<div><br /></div><div>Functions included are:</div><div><ul><li>Get-SmsWmi - Makes it easy to get WMI objects from the SMS Provider. (Note: call this function with no parameters to get a list of acceptable class nicknames)</li><li>Find-SmsId - Look up SMS WMI objects by ResourceID, CollectionID, PackageID, or AdvertisementID</li><li>Get-SmsCollectionTree - Inspired by tree.com from DOS, prints out the Collection structure of your site, with CollectionIDs and names.</li><li>Approve-Client - Marks an SCCM client as Approved in the SCCM DB.</li></ul><div>Don't forget to set the <span class="Apple-style-span" style="font-family:'courier new';"><b>$default_wmi_provider_server</b></span> and <span class="Apple-style-span" style="font-family:'courier new';"><b>$default_site</b></span> variables at the top of the module to match your environment. </div><div><br /></div><div><br /></div></div><br /><script type="text/javascript" src="http://PoshCode.org/embed/986"></script>Anonymoushttp://www.blogger.com/profile/17544382598989828904noreply@blogger.com0