{"id":12781,"date":"2011-09-06T00:01:00","date_gmt":"2011-09-06T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/09\/06\/learn-how-to-save-powershell-objects-for-offline-analysis\/"},"modified":"2011-09-06T00:01:00","modified_gmt":"2011-09-06T00:01:00","slug":"learn-how-to-save-powershell-objects-for-offline-analysis","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/learn-how-to-save-powershell-objects-for-offline-analysis\/","title":{"rendered":"Learn How to Save PowerShell Objects for Offline Analysis"},"content":{"rendered":"<p><strong>Summary<\/strong>: Learn how to use Windows PowerShell to save objects for later offline analysis.<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\" \/>Hey, Scripting Guy! I have a problem. I am trying to examine processes that are consuming resources on my computer. The problem is that when I use the <b>Get-Process<\/b> cmdlet, my results keep changing before I have a chance to examine thoroughly the output from my last output. I would like a way that I could store the command, and then analyze the results at my leisure. I know I can write to a text file, but I like having an object with which to work. In addition, I know that I can store the results in a variable, but I am a one person IT department at my company. I often have to leave my desk for extended periods of time, which means I cannot leave Windows PowerShell running all the time. What can I do?<\/p>\n<p>&mdash;BH<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\" \/>Hello BH,<\/p>\n<p>Microsoft Scripting Guy Ed Wilson here. I record two sessions for TechNet Radio this afternoon. I am beginning a series of monthly podcasts in which I will be discussing Windows PowerShell best practices. Of course, part of the discussion springs from my Microsoft Press book, <i>Windows PowerShell 2.0 Best Practices, <\/i>but other things discussed derive from things I saw during the 2011 Scripting Games, as well as questions I have received as the Scripting Wife and I have traveled around speaking at various conferences. Indeed, one of the best things about being the Microsoft Scripting Guy is the ability to talk to passionate people who are striving to use Windows PowerShell to solve real-world problems. &nbsp;<\/p>\n<p>One of the things that is really cool about Windows PowerShell is the way it makes working with processes so easy. On my antique laptop, I am very concerned with processes because they eat up precious memory resources, and they drain my aged battery of its limited life. I know I am not the only one in the world who faces restrictions in IT spending; luckily, Windows PowerShell provides a razor sharp tool that allows one to hone in on errant processes.<\/p>\n<p>BH, as you pointed out, it is easy to write process information to a text file. To do this, I use the redirection arrows from inside the Windows PowerShell console. I like to use the alias <b>gps<\/b> when working with the <b>Get-Process<\/b> cmdlet from console. The complete command to get all of the process information and write it to a text file is shown here:<\/p>\n<p style=\"padding-left: 30px\">gps &gt;&gt;<\/p>\n<p style=\"padding-left: 30px\">c:\\fso\\gps.txt<\/p>\n<p>The output that is stored in the text file is shown here.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1106.HSG-9-6-11-1.jpg\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of output stored in text file\" alt=\"Image of output stored in text file\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1106.HSG-9-6-11-1.jpg\" \/><\/a><\/p>\n<p>Depending on what you are attempting to accomplish, having a nicely formatted text file may just do the trick. On the other hand, if more than limited searching and perusal are in the forecast, a text file quickly outlasts its welcome.<\/p>\n<p>Of course, I can store the results of the command in a variable, and use all the power of Windows PowerShell to parse the data. For example, I can store my process information in a variable, and then sort the processes based on the amount of CPU time the processes are using. In the command that follows, I use the variable <b>$gps<\/b> to hold the process information that is retrieved by the <b>Get-Process<\/b> cmdlet. On the second line of the command, I pipe the <b>System.Diagnostics.Process<\/b> objects to the <b>Sort-Object<\/b> cmdlet (<b>sort<\/b> is an alias). I tell the <b>Sort-Object<\/b> cmdlet that I want to sort on the <b>cpu<\/b> property and I want that sort to be a descending sort (the biggest numbers on top). These two commands are shown here:<\/p>\n<p style=\"padding-left: 30px\">$gps = Get-Process<\/p>\n<p style=\"padding-left: 30px\">$gps | sort cpu &ndash;Descending<\/p>\n<p>The following figure contains both the commands and the output associated with those commands.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0083.hsg-9-6-11-2.jpg\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of commands and associated output\" alt=\"Image of commands and associated output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0083.hsg-9-6-11-2.jpg\" \/><\/a><\/p>\n<p>So it is easy to work with process objects in an offline fashion, as long as Windows PowerShell is kept running and the value stored in the <b>$gps<\/b> variable does not become overwritten. If I need to shut down Windows PowerShell or to reboot my computer, how can I continue to access the same process objects? I use the <b>Export-Clixml<\/b> cmdlet. I know the name of the cmdlet is a bit confusing, and for some it is downright scary. After all, most network administrators are skittish when it comes to XML.<\/p>\n<p>The cool thing about using the <b>Export-Clixml<\/b> cmdlet is that you do not need to know anything about XML to use it. All I am doing when I pipe my process information to the <b>Export-Clixml<\/b> cmdlet is using XML to store a representation of my objects. XML is the perfect choice for this. XML is a rich data store that easily adapts my objects for offline use. The command itself is simplicity and elegance personified. To obtain all the process information, I use the <b>Get-Process<\/b> cmdlet (<b>gps<\/b> is an alias), and I pipe the results to the <b>Export-Clixml<\/b> cmdlet. I provide the <b>Export-Clixml<\/b> cmdlet with a path to store the resultant XML file. This command is shown here:<\/p>\n<p style=\"padding-left: 30px\">gps | Export-Clixml c:\\fso\\gps.xml<\/p>\n<p>The resultant XML file is an actual XML file and is therefore viewable in an XML viewer, as shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3603.hsg-9-6-11-3.jpg\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of XML file in an XML viewer\" alt=\"Image of XML file in an XML viewer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3603.hsg-9-6-11-3.jpg\" \/><\/a><\/p>\n<p>After I have an XML representation of my process objects, I can import the XML file and work with the objects at any time in the future. I can reboot my computer 100 times, and still be able to open Windows PowerShell and view my offline process objects. In fact, I can use the XML file on a different computer if I need to do so.<\/p>\n<p>To import the XML for use on my computer, I use the <b>Import-CliXML<\/b> cmdlet. It only needs the path to the XML file. I can store the resultant process objects in a variable for ease of processing. In the following series of commands, I use the <b>Get-Process<\/b> cmdlet (<b>gps<\/b> is an alias) to retrieve process information. I pipe the objects to the <b>Export-CliXML<\/b> cmdlet and provide it with a path to store the resulting XML file. I then use the <b>Import-CliXML<\/b> cmdlet to import the XML file and store the process objects in the <b>$gps<\/b> variable. Next, I pipe the process objects to the <b>Where-Object<\/b> cmdlet (<b>?<\/b> Is an alias for <b>Where-Object<\/b>) where I look for process names that match <i>word. <\/i>The commands that accomplish all this are shown here:<\/p>\n<p style=\"padding-left: 30px\">gps | Export-Clixml c:\\fso\\gps.xml<\/p>\n<p style=\"padding-left: 30px\">$gps = Import-Clixml C:\\fso\\gps.xml<\/p>\n<p style=\"padding-left: 30px\">$gps | ? { $_.name -match &#8216;word&#8217; }<\/p>\n<p>The commands and associated output are shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1362.hsg-9-6-11-4.jpg\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of commands and associated output\" alt=\"Image of commands and associated output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1362.hsg-9-6-11-4.jpg\" \/><\/a><\/p>\n<p>I do not have to store the imported XML in a variable. I can simply use <b>Import-CliXML<\/b> and pipe the results directly into other Windows PowerShell cmdlets for processing. For example, if I want to look for duplicate processes that are running, I might import the XML file, <b>group<\/b> (alias for the <b>Group-Object<\/b> cmdlet) the processes on the <b>name<\/b> property, and <b>sort<\/b> (alias for the <b>Sort-Object<\/b> cmdlet) the results based on the <b>count<\/b> property in a descending fashion. The command that accomplishes this is shown here:<\/p>\n<p style=\"padding-left: 30px\">Import-Clixml C:\\fso\\gps.xml | group name -NoElement| sort count -des<\/p>\n<p>The command and associated output are shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6457.hsg-9-6-11-5.jpg\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of command and associated output\" alt=\"Image of command and associated output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6457.hsg-9-6-11-5.jpg\" \/><\/a><\/p>\n<p>One thing to keep in mind when working with <b>Import-CliXML<\/b> and <b>Export-CliXML<\/b> is that the created objects are deserialized. This means that the methods normally available to the <b>System.Diagnostics.Process<\/b> objects are not available. Other than that, they look and behave exactly like normal objects. I can pipe the XML to the <b>Get-Member<\/b> object to see what is available and what is not available. The command to do this is shown here:<\/p>\n<p style=\"padding-left: 30px\">Import-Clixml C:\\fso\\gps.xml | get-member<\/p>\n<p>The command and associated output are shown here.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6765.hsg-9-6-11-6.jpg\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of command and associated output\" alt=\"Image of command and associated output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6765.hsg-9-6-11-6.jpg\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Well, that is about all there is to working with offline objects and utilizing the <b>Import-CliXML<\/b> and <b>Export-CliXML <\/b>cmdlets. Join me tomorrow for more exciting Windows PowerShell stuff.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Learn how to use Windows PowerShell to save objects for later offline analysis. &nbsp; Hey, Scripting Guy! I have a problem. I am trying to examine processes that are consuming resources on my computer. The problem is that when I use the Get-Process cmdlet, my results keep changing before I have a chance to [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,31,87,3,4,45],"class_list":["post-12781","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-operating-system","tag-processes","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Learn how to use Windows PowerShell to save objects for later offline analysis. &nbsp; Hey, Scripting Guy! I have a problem. I am trying to examine processes that are consuming resources on my computer. The problem is that when I use the Get-Process cmdlet, my results keep changing before I have a chance to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12781","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=12781"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12781\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=12781"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=12781"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=12781"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}