{"id":86272,"date":"2019-08-27T22:49:21","date_gmt":"2019-08-28T06:49:21","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/scripting\/?p=86272"},"modified":"2019-08-29T11:21:43","modified_gmt":"2019-08-29T19:21:43","slug":"automating-quser-through-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/automating-quser-through-powershell\/","title":{"rendered":"Automating Quser through PowerShell"},"content":{"rendered":"<p><strong>Summary<\/strong>: Using PowerShell to automate Quser to identify users to Logoff systems in Windows<\/p>\n<p>Hey Doctor Scripto! I need to log a user off every computer they\u2019re logged into. The problem is, I don\u2019t know which ones. How can I discover which computers they\u2019re logged into and then log them off?<\/p>\n<p>That&#8217;s a most excellent question!\u00a0 I know just the person who can answer that. \u00a0 I was talking my good friend Dan Reist on this topic. \u00a0 Dan is a Senior Consultant on Data Platforms here at Microsoft. \u00a0 He actually ran into that same issue.<\/p>\n<p>Dan, the room is yours today, take it away!<\/p>\n<p>Thanks Doctor Scripto!<\/p>\n<p>So my first thought to that is &#8220;Very carefully!&#8221;\u00a0 Let\u2019s simplify the question by looking at one specific computer.<\/p>\n<p>First, let\u2019s define the username and computer name we\u2019re investigating.<\/p>\n<pre class=\"lang:default decode:true\">$userName = \u2018randomnote1\u2019\r\n$computer = \u2018sqlserver01\u2019<\/pre>\n<p>Now, let\u2019s use the <strong>quser<\/strong> (query user) command to get all the user sessions on the computer.<\/p>\n<pre class=\"lang:default decode:true\">$quserResult = quser \/server:$computer 2&gt;&amp;1<\/pre>\n<p>When we examine the contents of the <strong>$quserResult<\/strong> variable it contains a nicely formatted table<\/p>\n<pre class=\"lang:default decode:true\">USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME\r\nrandomnote1 console 1 Active none 8\/14\/2019 6:52 AM<\/pre>\n<p>Cool, we can clearly see that the user randomnote1 is logged onto this computer. The problem is, this is just a string array. Not very easy to work with! However, it looks like the table is formatted with at least two spaces between each column. That should be easy to replace with some commas to make a CSV!<\/p>\n<pre class=\"lang:ps decode:true\">$quserRegex = $quserResult | ForEach-Object -Process { $_ -replace '\\s{2,}',',' }<\/pre>\n<p>Now when we look at the contents of <strong>$quserRegex<\/strong>, we can see an array of comma separated values.<\/p>\n<p><strong>USERNAME,SESSIONNAME,ID,STATE,IDLE TIME,LOGON TIME\n<\/strong><strong>randomnote1,console,1,Active,none,8\/14\/2019 6:52 AM<\/strong><\/p>\n<p>Now we\u2019re getting somewhere. Let\u2019s use <strong>ConvertFrom-Csv<\/strong> to convert the CSV into a PowerShell object.<\/p>\n<pre class=\"lang:ps decode:true\">$quserObject = $quserRegex | ConvertFrom-Csv<\/pre>\n<p>Look at the contents of <strong>$quserObject<\/strong>, we can see it now looks like a PowerShell object!<\/p>\n<p><strong>USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME\n<\/strong><strong>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\n<\/strong><strong>randomnote1 console 1 Active none 8\/14\/2019 6:52 AM<\/strong><\/p>\n<p>Finally, we can extract the session id for the user we need to log off and log the user off the computer!<\/p>\n<pre class=\"lang:ps decode:true\">$userSession = $quserObject | Where-Object -FilterScript { $_.USERNAME -eq 'randomnote1' }\r\nlogoff $userSession.ID \/server:$computer<\/pre>\n<p>That\u2019s all there is to it! Now you can operationalize it by performing these steps over an array of computers.<\/p>\n<pre class=\"lang:ps decode:true\">$computers = Get-ADComputer -Filter * | Select-Object -ExpandProperty Name\r\nforeach ( $computer in $computers )\r\n{\r\n\t$quserResult = quser \/server:$computer 2&gt;&amp;1\r\n\tIf ( $quserResult.Count -gt 0 )\r\n{\r\n\t\t$quserRegex = $quserResult | ForEach-Object -Process { $_ -replace '\\s{2,}',',' }\r\n\t\t$quserObject = $quserRegex | ConvertFrom-Csv\r\n\t\t$userSession = $quserObject | Where-Object -FilterScript { $_.USERNAME -eq 'randomnote1' }\r\n\t\tIf ( $userSession )\r\n\t\t{\r\n\t\t\tlogoff $userSession.ID \/server:$computer\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<p>Thank you Dan!\u00a0 That&#8217;s not only a cool trick but a beautiful example of using both legacy Console commands and PowerShell together to produce a new solution!<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\">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\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\">Official Scripting Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Your good friend, Doctor Scripto<\/strong><\/p>\n<p>Doctor Scripto, Dan Reist, PowerShell<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Using PowerShell to automate Quser to identify users to Logoff systems in Windows Hey Doctor Scripto! I need to log a user off every computer they\u2019re logged into. The problem is, I don\u2019t know which ones. How can I discover which computers they\u2019re logged into and then log them off? That&#8217;s a most excellent [&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":[1930,1739,1738,687],"tags":[1931,1740,377,174],"class_list":["post-86272","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-200-level","category-doctor-scripto","category-powershell","category-regular-expressions","tag-dan-reist","tag-doctor-scripto","tag-powershell","tag-regular-expressions"],"acf":[],"blog_post_summary":"<p>Summary: Using PowerShell to automate Quser to identify users to Logoff systems in Windows Hey Doctor Scripto! I need to log a user off every computer they\u2019re logged into. The problem is, I don\u2019t know which ones. How can I discover which computers they\u2019re logged into and then log them off? That&#8217;s a most excellent [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/86272","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=86272"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/86272\/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=86272"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=86272"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=86272"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}