{"id":92,"date":"2007-03-24T00:24:00","date_gmt":"2007-03-24T05:24:00","guid":{"rendered":"http:\/\/wangxiaohu.com\/blog\/?p=92"},"modified":"2007-03-24T00:24:00","modified_gmt":"2007-03-24T05:24:00","slug":"let-powershell-to-summarize-your-im-history","status":"publish","type":"post","link":"https:\/\/wangxiaohu.com\/blog\/?p=92","title":{"rendered":"Let PowerShell to summarize your IM history"},"content":{"rendered":"<p><strong>(March 25, 2007) Update: <\/strong><strong>Thanks to James Manning for the <font face=\"Consolas\">-passthru<\/font> parameter to simply the command.<\/strong><\/p>\n<p><a href=\"http:\/\/www.microsoft.com\/windowsserver2003\/technologies\/management\/powershell\/default.mspx\">Windows PowerShell<\/a>, also known as &#8220;Monad&#8221;, is a cool shell environment to replace old CMD shell under Windows. It is an object oriented shell and it allow easy manipulation of different types of objects interactively.&nbsp;Another advantage is&nbsp;the support of&nbsp;various data structures and formats, such as XML. Just like other good old shells, it also supports piping. The difference is that, instead of text stream, it sends objects through&nbsp;the pipes.<\/p>\n<p>I always want to find out some information about my&nbsp;<a href=\"http:\/\/messenger.live.com\">Live Messenger<\/a>&nbsp;history. Now let&#8217;s see what PowerShell can do with it. In most cases, Live Messenger history&nbsp;is saved&nbsp;under &#8220;<em>My Received Files\\&lt;Live ID with some numbers&gt;\\History<\/em>&#8221; in your <em>Document<\/em> folder. Now let&#8217;s boot into PowerShell and &#8220;<font face=\"Consolas\">Set-Location<\/font>&#8221; or&nbsp;&#8221;<font face=\"Consolas\">cd<\/font>&#8221; to this folder. If you type &#8220;<font face=\"Consolas\">Get-ChildItem<\/font>&#8221; or &#8220;<font face=\"Consolas\">dir<\/font>&#8221; you will see a bunch of <font face=\"Consolas\">.xml<\/font> files listed.<\/p>\n<p>Alright, let&#8217;s first try to find the <strong>top 10 friends with most letters<\/strong>:<\/p>\n<div class=\"csharpcode-wrapper\">\n<div class=\"csharpcode\">\n<pre class=\"alt\">Get-ChildItem | Sort-Object Length -descending | Select-Object -first 10<\/pre>\n<\/div>\n<style type=\"text\/css\">.csharpcode-wrapper, .csharpcode-wrapper pre {\n  background-color: #f4f4f4;\n  border: solid 1px gray;\n  cursor: text;\n  font-family: consolas, \\'Courier New\\', courier, monospace;\n  font-size: 8pt;\n  line-height: 12pt;\n  margin: 20px 0px 10px 0px;\n  max-height: 200px;\n  overflow: auto;\n  padding: 4px 4px 4px 4px;\n  width: 97.5%;\n}\n.csharpcode-wrapper pre {\n  border-style: none;\n  margin: 0px 0px 0px 0px;\n  overflow: visible;\n  padding: 0px 0px 0px 0px;\n}\n.csharpcode, .csharpcode pre, .csharpcode .alt {\n  background-color: #f4f4f4;\n  border-style: none;\n  color: black;\n  font-family: consolas, \\'Courier New\\', courier, monospace;\n  font-size: 8pt;\n  line-height: 12pt;\n  overflow: visible;\n  padding: 0px 0px 0px 0px;\n  width: 100%;\n}\n.csharpcode pre {\n  margin: 0em;\n}\n.csharpcode .alt {\n  background-color: white;\n}\n.csharpcode .asp {\n  background-color: #ffff00;\n}\n.csharpcode .attr {\n  color: #ff0000;\n}\n.csharpcode .html {\n  color: #800000;\n}\n.csharpcode .kwrd {\n  color: #0000ff;\n}\n.csharpcode .lnum {\n  color: #606060;\n}\n.csharpcode .op {\n  color: #0000c0;\n}\n.csharpcode .preproc {\n  color: #cc6633;\n}\n.csharpcode .rem {\n  color: #008000;\n}\n.csharpcode .str {\n  color: #006080;\n}\n<\/style>\n<\/div>\n<p>At this point, I assume you are already familiar with the concept of piping. Here it gets a list of files, sort it and display the first 10. That&#8217;s not too difficult to understand.<\/p>\n<p>Actually those files are in XML format. That&#8217;s why it ends with <font face=\"Consolas\">.xml<\/font> extension. One important XML&nbsp;element in these files&nbsp;is the <font face=\"Consolas\">message<\/font>.&nbsp;Each <font face=\"Consolas\">message<\/font> element corresponds to a sentence sent between me and my friend. Let&#8217;s see how PowerShell deals with XML files in this case. The following command lists the <strong>top 10 friends with most messages<\/strong>:<\/p>\n<div class=\"csharpcode-wrapper\">\n<div class=\"csharpcode\">\n<pre class=\"alt\">Get-ChildItem |<\/pre>\n<pre>ForEach-Object {<\/pre>\n<pre class=\"alt\">    $_ |<\/pre>\n<pre>    Add-Member noteproperty -name count -value ([XML] (Get-Content $_ -Encoding UTF8)).Log.Message.Count -passthru<\/pre>\n<pre class=\"alt\">} |<\/pre>\n<pre>Sort-Object -property count -descending |<\/pre>\n<pre class=\"alt\">Select-Object -first 10 |<\/pre>\n<pre>Format-Table count,Name<\/pre>\n<\/div>\n<style type=\"text\/css\">.csharpcode-wrapper, .csharpcode-wrapper pre {\n  background-color: #f4f4f4;\n  border: solid 1px gray;\n  cursor: text;\n  font-family: consolas, \\'Courier New\\', courier, monospace;\n  font-size: 8pt;\n  line-height: 12pt;\n  margin: 20px 0px 10px 0px;\n  max-height: 200px;\n  overflow: auto;\n  padding: 4px 4px 4px 4px;\n  width: 97.5%;\n}\n.csharpcode-wrapper pre {\n  border-style: none;\n  margin: 0px 0px 0px 0px;\n  overflow: visible;\n  padding: 0px 0px 0px 0px;\n}\n.csharpcode, .csharpcode pre, .csharpcode .alt {\n  background-color: #f4f4f4;\n  border-style: none;\n  color: black;\n  font-family: consolas, \\'Courier New\\', courier, monospace;\n  font-size: 8pt;\n  line-height: 12pt;\n  overflow: visible;\n  padding: 0px 0px 0px 0px;\n  width: 100%;\n}\n.csharpcode pre {\n  margin: 0em;\n}\n.csharpcode .alt {\n  background-color: white;\n}\n.csharpcode .asp {\n  background-color: #ffff00;\n}\n.csharpcode .attr {\n  color: #ff0000;\n}\n.csharpcode .html {\n  color: #800000;\n}\n.csharpcode .kwrd {\n  color: #0000ff;\n}\n.csharpcode .lnum {\n  color: #606060;\n}\n.csharpcode .op {\n  color: #0000c0;\n}\n.csharpcode .preproc {\n  color: #cc6633;\n}\n.csharpcode .rem {\n  color: #008000;\n}\n.csharpcode .str {\n  color: #006080;\n}\n<\/style>\n<\/div>\n<p>It&nbsp;first gets a list of files. For each file, <strike>it creates a new object <font face=\"Consolas\">$o.<\/font> Then<\/strike> it adds the count of messages&nbsp;from&nbsp;the XML file as a property <strike>of <font face=\"Consolas\">$o<\/font>, as well as the name of each file<\/strike>. Finally, it sorts the object based on number of messages and displays the top 10. <\/p>\n<p>Another interesting XML element of Live Messenger history file is <font face=\"Consolas\">LastSessionID<\/font>. I guess It is the number of chat sessions established by either&nbsp;me or my friend.&nbsp;With a little modification to the previous command, I can know the <strong>top 10 friends with&nbsp;most sessions<\/strong>:<\/p>\n<div class=\"csharpcode-wrapper\">\n<div class=\"csharpcode\">\n<pre class=\"alt\">Get-ChildItem |<\/pre>\n<pre>ForEach-Object {<\/pre>\n<pre class=\"alt\">    $_ |<\/pre>\n<pre>    Add-Member noteproperty -name count -value ([Int32] ([XML] (Get-Content $_ -Encoding UTF8)).Log.LastSessionID) -passthru<\/pre>\n<pre class=\"alt\">} |<\/pre>\n<pre>Sort-Object -property count -descending |<\/pre>\n<pre class=\"alt\">Select-Object -first 10 |<\/pre>\n<pre>Format-Table count,Name<\/pre>\n<\/div>\n<style type=\"text\/css\">.csharpcode-wrapper, .csharpcode-wrapper pre {\n  background-color: #f4f4f4;\n  border: solid 1px gray;\n  cursor: text;\n  font-family: consolas, \\'Courier New\\', courier, monospace;\n  font-size: 8pt;\n  line-height: 12pt;\n  margin: 20px 0px 10px 0px;\n  max-height: 200px;\n  overflow: auto;\n  padding: 4px 4px 4px 4px;\n  width: 97.5%;\n}\n.csharpcode-wrapper pre {\n  border-style: none;\n  margin: 0px 0px 0px 0px;\n  overflow: visible;\n  padding: 0px 0px 0px 0px;\n}\n.csharpcode, .csharpcode pre, .csharpcode .alt {\n  background-color: #f4f4f4;\n  border-style: none;\n  color: black;\n  font-family: consolas, \\'Courier New\\', courier, monospace;\n  font-size: 8pt;\n  line-height: 12pt;\n  overflow: visible;\n  padding: 0px 0px 0px 0px;\n  width: 100%;\n}\n.csharpcode pre {\n  margin: 0em;\n}\n.csharpcode .alt {\n  background-color: white;\n}\n.csharpcode .asp {\n  background-color: #ffff00;\n}\n.csharpcode .attr {\n  color: #ff0000;\n}\n.csharpcode .html {\n  color: #800000;\n}\n.csharpcode .kwrd {\n  color: #0000ff;\n}\n.csharpcode .lnum {\n  color: #606060;\n}\n.csharpcode .op {\n  color: #0000c0;\n}\n.csharpcode .preproc {\n  color: #cc6633;\n}\n.csharpcode .rem {\n  color: #008000;\n}\n.csharpcode .str {\n  color: #006080;\n}\n<\/style>\n<\/div>\n<p>A small change is that <font face=\"Consolas\">LastSessionsID<\/font> is read as a string. So we have to convert it to a integer number using <font face=\"Consolas\">[Int32]<\/font>.<\/p>\n<p>Other XML elements, such as <font face=\"Consolas\">Date<\/font>, <font face=\"Consolas\">Time<\/font> and even <font face=\"Consolas\">text<\/font> in each <font face=\"Consolas\">message<\/font>, are very informative too, as long as you can explorer them in a good way. Right now, there are other more information I can think of out of my head,&nbsp;e.g. the top 10 longest message you received, the first 10 person talked with you, the longest 10 chat sessions in your IM history and so on.<\/p>\n<p>For updated information and tricks on PowerShell,&nbsp;<a href=\"http:\/\/blogs.msdn.com\/powershell\/\">here<\/a> is a good resource. If you have used Live Messenger on two or more computers, you might also want to consider this<a href=\"http:\/\/www.codeplex.com\/MsnHistoryMerger\"> history merger<\/a>.<\/p>\n<p>Guess who sends the most smiles to me? \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>(March 25, 2007) Update: Thanks to James Manning for th &hellip; <a href=\"https:\/\/wangxiaohu.com\/blog\/?p=92\" class=\"more-link\">\u7ee7\u7eed\u9605\u8bfb<span class=\"screen-reader-text\">Let PowerShell to summarize your IM history<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[1],"tags":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","jetpack_likes_enabled":true,"jetpack-related-posts":[],"jetpack_shortlink":"https:\/\/wp.me\/pdhZ2A-1u","_links":{"self":[{"href":"https:\/\/wangxiaohu.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/92"}],"collection":[{"href":"https:\/\/wangxiaohu.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wangxiaohu.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wangxiaohu.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/wangxiaohu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=92"}],"version-history":[{"count":0,"href":"https:\/\/wangxiaohu.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/92\/revisions"}],"wp:attachment":[{"href":"https:\/\/wangxiaohu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=92"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wangxiaohu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=92"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wangxiaohu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=92"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}