{"id":15951,"date":"2011-01-10T00:01:00","date_gmt":"2011-01-10T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/01\/10\/provide-input-to-applications-with-powershell\/"},"modified":"2011-01-10T00:01:00","modified_gmt":"2011-01-10T00:01:00","slug":"provide-input-to-applications-with-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/provide-input-to-applications-with-powershell\/","title":{"rendered":"Provide Input to Applications with PowerShell"},"content":{"rendered":"<p><span style=\"font-size:10.0pt\">&nbsp;<\/span><span style=\"font-size:10.0pt\">&nbsp;<\/span><\/p>\n<p><b><span style=\"font-size:10.0pt\">Summary:<\/span><\/b><span style=\"font-size:10.0pt\"> Use SendKeys to provide input to graphical applications with Windows PowerShell.<\/span><\/p>\n<p><span style=\"font-size:10.0pt\">&nbsp;<\/span><\/p>\n<p><span style=\"font-size:10.0pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Question\" border=\"0\" title=\"Hey, Scripting Guy! Question\" \/><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>Hey, Scripting Guy! I am almost embarrassed to admit this but you know what I miss most about VBScript? I miss the <b>SendKeys<\/b> function. I do not know why Windows PowerShell did not include a <b>New-SendKeys<\/b> cmdlet. I know all about the risks, about losing focus, and that, depending on what a user has open on their computer, things may go amiss but the simple fact is, that sometimes I must be able to send a keystroke to an application. A perfect example is a recent software update from Microsoft Update&mdash;the Live Essentials update. It stops processing until someone checks <b>OK<\/b> and presses <b>Enter<\/b>. This is really difficult to manage when a computer is downloading 17 updates that total 186 Megabytes. One does not know whether the long pause is because the &ldquo;Internet is slow&rdquo; or because some dialog box that is prompting for user interaction is hidden behind a forest of windows. Sorry for the rant, but as you might suspect, I was just burned by this. <\/span><\/p>\n<p><span style=\"font-size:10.0pt\">&#8212; MB<\/span><\/p>\n<p><span style=\"font-size:10.0pt\">&nbsp;<\/span><\/p>\n<p><span style=\"font-size:10.0pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Answer\" border=\"0\" title=\"Hey, Scripting Guy! Answer\" \/><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>Hello MB, Microsoft Scripting Guy Ed Wilson here. Remember, tomorrow is <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2008\/01\/15\/how-can-i-add-a-record-to-a-database-using-windows-powershell.aspx\">Scripting Guys Day<\/a>. I was out in my woodworking shop yesterday making some hand-cut dovetails for a box I am building out of walnut, when it dawned on me that tomorrow is Scripting Guys Day, and I did not even buy myself a present. Well that is what is so great about the Internet, I can easily correct that oversight. Hmm, maybe a nice 15-inch <a href=\"http:\/\/en.wikipedia.org\/wiki\/Jack_plane\">Jack Plane<\/a>&hellip; <\/span><\/p>\n<p><span style=\"font-size:10.0pt\">MB, the old VBScript SendKeys function was one of those things that people loved to hate. VBScripters used it because there was no other option. In Windows PowerShell, there are actually two other options for GUI Automation. There is a good MSDN article that <a href=\"http:\/\/msdn.microsoft.com\/en-us\/magazine\/cc163301.aspx\">discusses UI Automation for program testing<\/a>. The second option is a <a href=\"http:\/\/www.codeplex.com\/site\/search?projectSearchText=powershell%20module\">codeplex<\/a> project named <a href=\"http:\/\/wasp.codeplex.com\/\">WASP (Windows Automation Snapin for PowerShell).<\/a> <\/span><\/p>\n<p><span style=\"font-size:10.0pt\">There is nothing wrong with using the VBScript <b>SendKeys<\/b> function inside Windows PowerShell. In fact, I <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2008\/10\/16\/how-can-i-create-passwords-for-my-users.aspx\">talked about this in a Hey, Scripting Guy! post last year<\/a> in a discussion about passwords. A .NET Framework <b>SendKeys<\/b> class can also be utilized. <\/span><\/p>\n<p><span style=\"font-size:10.0pt\">When you use <b>SendKeys<\/b> (either the VBScript function, or the .NET Framework class) it is important to call the target application to the foreground. If you do not do this, whatever application has the foreground will receive the keystrokes. With just a bit of imagination I am sure that you could devise your own worst case scenarios for self-inflicted disaster! <\/span><\/p>\n<p><span style=\"font-size:10.0pt\">I actually ran across the following problem while writing todays script. In my first script, I did not include a <b>start-sleep <\/b>command to pause the script execution. The reason for pausing the script is to allow the application (Calculator in this example) to fully initialize. Calculator is a very lightweight application, and it loads very quickly. Unfortunately, it does not load instantly. When I first ran my script, the <b>appactivate<\/b> method failed because Calculator was not in memory when the line of code was called. Therefore, my Windows PowerShell ISE was still in the foreground when <b>SendKeys<\/b> added some &ldquo;new code&rdquo; to my script. If I had not been paying attention, and if I had saved the script on exit, my script would have been hosed. The results of this are seen in the following figure.<\/span><\/p>\n<p><span style=\"font-size:10.0pt\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/1222.HSG-1-10-11-01.jpg\" border=\"0\" \/><\/span><span style=\"font-size:10.0pt\">&nbsp;<\/span><\/p>\n<p><span style=\"font-size:10.0pt\">Because Calculator loads quickly, I added a 500 millisecond pause to the script. The revised <b>SendKeys.ps1<\/b> script is seen here.<\/span><\/p>\n<p class=\"CodeBlockScreenedHead\" style=\"padding-left: 30px;background: none transparent scroll repeat 0% 0%\"><span style=\"font-size:10.0pt\"><strong>SendKeys.ps1<\/strong><\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"padding-left: 30px;background: none transparent scroll repeat 0% 0%\"><span style=\"font-size: 10pt\"><span style=\"font-family: courier new,courier\">add-type -AssemblyName microsoft.VisualBasic<\/span><\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"padding-left: 30px;background: none transparent scroll repeat 0% 0%\"><span style=\"font-size: 10pt\"><span style=\"font-family: courier new,courier\">add-type -AssemblyName System.Windows.Forms<\/span><\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"padding-left: 30px;background: none transparent scroll repeat 0% 0%\"><span style=\"font-size: 10pt\"><span style=\"font-family: courier new,courier\">Calc<\/span><\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"padding-left: 30px;background: none transparent scroll repeat 0% 0%\"><span style=\"font-size: 10pt\"><span style=\"font-family: courier new,courier\">start-sleep -Milliseconds 500<\/span><\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"padding-left: 30px;background: none transparent scroll repeat 0% 0%\"><span style=\"font-size: 10pt\"><span style=\"font-family: courier new,courier\">[Microsoft.VisualBasic.Interaction]::AppActivate(&#8220;Calc&#8221;)<\/span><\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"padding-left: 30px;background: none transparent scroll repeat 0% 0%\"><span style=\"font-size: 10pt\"><span style=\"font-family: courier new,courier\">[System.Windows.Forms.SendKeys]::SendWait(&#8220;1{ADD}1=&#8221;)<\/span><\/span><\/p>\n<p><span style=\"font-size:10.0pt\">&nbsp;<\/span><\/p>\n<p><span style=\"font-size:10.0pt\">The two .NET Framework classes that are used in the <b>SendKeys.ps1<\/b> script are not loaded by default. To provide access to these, it is necessary to load the assemblies. In <a href=\"http:\/\/support.microsoft.com\/kb\/968929\">Windows PowerShell 2.0<\/a>, it is easiest to use the <b>Add-Type<\/b> Windows PowerShell cmdlet to load assemblies. In Windows PowerShell 1.0 it was common to use the <b>LoadWithPartialName <\/b>static method from the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.reflection.assembly.aspx\">System.Reflection.Assembly<\/a> .NET class. However, that <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.reflection.assembly_methods.aspx\">method is obsolete and therefore it should not be used<\/a>. <\/span><\/p>\n<p><span style=\"font-size:10.0pt\">After the two assemblies are loaded, I call the calc executable to load Calculator. Because I am not doing anything other than launching Calculator, there is no need to use the <b>Start-Process<\/b> Windows PowerShell cmdlet to start the calc process. <\/span><\/p>\n<p><span style=\"font-size:10.0pt\">As mentioned earlier, I have to provide a pause to allow the Calculator application to launch. The 500 millisecond timing works on my computer but it might not work on your computer! The <b>start-sleep<\/b> Windows PowerShell cmdlet will accept a pause value in seconds also. For example, to pause the script for 2 seconds, the command would appear as indicated here.<\/span><\/p>\n<p class=\"CodeBlock\" style=\"text-align: left;margin-left: 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: courier new,courier\">Start-Sleep &ndash;Seconds 2<\/span><\/span><\/p>\n<p><span style=\"font-size:10.0pt\">&nbsp;<\/span><\/p>\n<p><span style=\"font-size:10.0pt\">If you are working with a larger application or with a variety of computers with different processing capabilities, it would be best to modify the script to use an event. I have written a number of <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/windows+powershell\/events+and+monitoring\/\">Hey, Scripting Guy! posts that talk about consuming events from Windows PowerShell scripts<\/a>. <\/span><\/p>\n<p><span style=\"font-size:10.0pt\">When the script runs, Calculator will appear, and the numbers sent via the <b>SendWait <\/b>method will update. This is seen in the following figure.<\/span><\/p>\n<p><span style=\"font-size:10.0pt\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/5873.HSG-1-10-11-02.jpg\" border=\"0\" \/><\/span><span style=\"font-size:10.0pt\">&nbsp;<\/span><\/p>\n<p><span style=\"font-size:10.0pt\"><\/span><\/p>\n<p><span style=\"font-size:10.0pt\">MB, that is all there is to using <b>SendKeys<\/b> to provide input to an application. Input week will continue tomorrow. <\/span><\/p>\n<p><span style=\"font-size:10.0pt\">I invite you to follow me on <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingguystwitter\">Twitter<\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. aSee you tomorrow. Until then, peace.<\/span><\/p>\n<p><span style=\"font-size:10.0pt\">&nbsp;<\/span><\/p>\n<p><b><span style=\"font-size:10.0pt\">Ed Wilson, Microsoft Scripting Guy<\/span><\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp;&nbsp; Summary: Use SendKeys to provide input to graphical applications with Windows PowerShell. &nbsp; Hey, Scripting Guy! I am almost embarrassed to admit this but you know what I miss most about VBScript? I miss the SendKeys function. I do not know why Windows PowerShell did not include a New-SendKeys cmdlet. I know all about [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[2,3,4,45],"class_list":["post-15951","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-running","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp;&nbsp; Summary: Use SendKeys to provide input to graphical applications with Windows PowerShell. &nbsp; Hey, Scripting Guy! I am almost embarrassed to admit this but you know what I miss most about VBScript? I miss the SendKeys function. I do not know why Windows PowerShell did not include a New-SendKeys cmdlet. I know all about [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/15951","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=15951"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/15951\/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=15951"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=15951"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=15951"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}