Tag Archives: powershell

Automate a Microsoft software with Powershell

Read my intro to Powershell yet?

Anyway, what I’m about to explain here assumes that you have a basic understanding of Powershell, so you should read a real and complete tutorial on the subject.

To control a software with Powershell, you must first put your hand on it. The easy way is to start it yourself and put the result in a variable, such as shown here:

$x = New-Object -com Excel.Application

Than you can make it visible:

$x.Visible = $true

… and change some value in an active cell:

$a.ActiveCell.Value2 = "x"

Basic Powershell 101 (which should blow your mind, if you never saw it before).

But how can you get a grip on an application that is already running? Say I have a Visio document and need to add automatically some little things in it. In this case, you can store the Visio application with the following:

$visio = [Runtime.InteropServices.Marshal]::GetActiveObject("Visio.Application")

This was the only really tricky part. Everything else can be found in the Visio Automation Object Model Reference.

Obtaining the Visio application would be much easier for future uses with a function:

function get-visio {[Runtime.InteropServices.Marshal]::GetActiveObject("Visio.Application")}

Now let’s try our shiny new methods. How can I publish a page to PDF from Powershell? With the ExportAsFixedFormat method. This method is applicable to a Visio’s document. How do we select one?

$visio_doc = $visio.activedocument

Or in a function:

function get-visiodoc {Param ($visio_instance)
  $visio_instance.activedocument}

This way, we can obtain the active document with the following:

$visio_doc = (get-visiodoc (get-visio))

And now the method itself:

$visio_doc.ExportAsFixedFormat(1,"test-publish.pdf",1,1,1,1,$false,$true,$false,$false,$true)

This will export a single page PDF named “test-publish.pdf”. Ok, not really useful in itself. What if we want to export every page from the document in as many PDF? This is becoming quite a clicking-heavy task for a menu user. Not with Powershell!

Start with a single page publish function:

function export-page-pdf {param ($visio_page, $visio_path = "")
    $filename = $visio_path + $visio_page.name + ".pdf"
$page_to_export = $visio_page.index
    (get-visiodoc (get-visio)).exportasfixedformat(1,$filename,1,1,$page_to_export,$page_to_export,$false,$true,$false,$false,$true)}

Notice the optional argument $visio_path.

And now a looping function to publish every single page of the document:

function export-document-pdf {
    $active_document = (get-visio).activedocument
$document_path = $active_document.path
$active_document.pages | foreach-object {export-page-pdf $_ $document_path }}

Tada! The export-document-pdf function doesn’t require any argument, so simply calling it will result in every page being published in PDF! You can even save the function and pin it to your taskbar. Next time you want to export a document, “click”, done!

With this example and the Visio Automation Object Model Reference, you should be able to do great things! Godspeed!


Intro to Powershell

After all those articles on Emacs, you must have categorized me as an Emacs zealot. But fear not! I do use other software to help me in my daily work!

Today I will do a quick intro on Powershell, because let’s face it, the overwhelming majority of people use Windows. Hell, even I do!

PS for Powershell

Let’s start by running Powershell. Press the keys Win-r and then type Powershell RET. Boom! You now have the power of Powershell under your fingertips. Oh, before I forget, there is an emacs mode for PS…

First command: get-process You should see your machine’s process appear. Here is a little part of what I get with this command:

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    462      29    13180      25888   133    33,23    264 agent
     36       7    24196      26748    65     0,11  41188 aspell
    131      11    16660      16860    51           19676 audiodg
   1369     536    97432      62972   407   649,50   1272 AvastSvc
    519      53    12088      14396   150    30,20   4072 AvastUI
    118      14     6616      12388   110     5,04   2172 BTTray
    141      20    15044      25332   155    30,56   2812 chrome
    135      31    45784      56472   173     2,01   6632 chrome
...

The next command is “pipeline” |. It takes the results from a command and send it to the next one. Imagine I wanted to know what was my most CPU intensive process at the moment. Open task manager and check the CPU? Pffff! Here’s what you do:

get-process | sort
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    462      29    13180      25888   133    33,23    264 agent
     36       7    24196      26748    65     0,11  41188 aspell
    131      11    16660      16860    51           19676 audiodg
   1369     536    97432      62972   407   649,50   1272 AvastSvc
...

Wait… Oh! It’s sorted by name! But how can you sort it by CPU?

get-process | sort cpu
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
     63       7     2252       4184    35     0,02   2712 WLIDSVCM
     45       7     2208       6192    63     0,03  28704 conhost
     48       7     2260       6256    63     0,03  43240 conhost
    104       9     3328       7412    35     0,06  33088 SearchFilterHost
    284      12     3548       9528    57     0,09  29188 SearchProtocolHost
     33       2      564       1232     5     0,11    352 smss
...

We’re almost there! It’s sorted in ascending order. We can check the last process in the list (boring), or change the order:

get-process | sort cpu -descending
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    691     140    46820     107716   273 ...82,32   1580 dwm
   1141      69   205032     174472   666 ...42,59  18564 chrome
     88      46     6452      13752    90 ...61,14   4248 dthtml
   1123      39   142216     149144   322 ...98,77   1016 svchost
...

Yay!

A real example

This is all fun and dandy, but hardly useful for the common user. Here is a more common scenario: You have written a file in a the last week, but can’t figure out where you have put it. Powershell to the rescue!

get-childitem -path "C:\" -recurse | where-object {$_.lastwritetime -gt (Get-date).AddDays(-7)}

This little command will scan the entire C directory (with the help of -recurse) and return any files written after this day - 7 days. Be careful with recurse, a full hard drive scan can be quite long! On the other hand, you can continue working while Powershell does its scan in the background.

There’s something more we can do. If we search for a particular type of file, we can pipeline once again the results and filter it to return only what interests us. If we want a .org file:

get-childitem -path "C:\" -recurse | where-object {$_.lastwritetime -gt (Get-date).AddDays(-7)} |`
where-object {$_.name -like "*.org"}
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2011-12-13     19:51       2532 compare-two-files.org
-a---        2011-11-29     22:05        934 dilbert.org
-a---        2011-12-12     21:36       3922 On-automation.org
...

Oh! There is my missing file!