wilsond has asked for the wisdom of the Perl Monks concerning the following question:

Edit: Fixed. Needed to use LetProperty. New version of Win32::WindowsUpdate (version 0.3) should be finding its way around the CPAN rather soon. It will let you install your Windows Updates as expected.


I've created a new module called Win32::WindowsUpdate. Version 0.1 is up on the CPAN, but it only tells you if you have updates to install and tells you which updates are installed. It doesn't actually install anything. I've written the code that I thought would do exactly that, but I'm having trouble. Here's the code that I thought would do it:

sub new { my $class = shift; my $args = shift; my $self = {}; $self->{online} = (defined($args->{online}) ? ($args->{online} ? 1 : + 0) : 1); # online by default $self->{updateSession} = Win32::OLE->new('Microsoft.Update.Session') + or die "ERROR creating Microsoft.Update.Session\n"; $self->{updateSearcher} = $self->{updateSession}->CreateUpdateSearch +er or die "ERROR creating CreateUpdateSearcher\n"; $self->{updateSearcher}->{Online} = $self->{online}; return bless($self, $class); } # .. cut unrelated stuff .. sub install { my $self = shift; my @updates = @_; my $updatecoll = Win32::OLE->new('Microsoft.Update.UpdateColl') or d +ie "ERROR creating Microsoft.Update.UpdateColl\n"; $updatecoll->Clear; my $queryResult = $self->{updateSearcher}->Search("IsInstalled = 0 A +ND IsHidden = 0") or die "ERROR in query\n"; my $updates = $queryResult->Updates; foreach my $update (in $updates) { my $updateID = $update->Identity->UpdateID; next unless grep(m/^$updateID$/i, @updates); $update->AcceptEula; $updatecoll->Add($update); printf("Adding %s %s to collection\n", $updateID, $update->Title); } printf("Updates to install: %d\n", $updatecoll->Count); my $downloader = $self->{updateSession}->CreateUpdateDownloader; $downloader->{Updates} = $updatecoll; my $downloadResult = $downloader->Download; my $installer = $self->{updateSession}->CreateUpdateInstaller; $installer->{Updates} = $updatecoll; $installer->{AllowSourcePrompts} = 0; $installer->{ForceQuiet} = 1; my $installResult = $installer->Install; use Data::Dumper; print Dumper($updatecoll, $downloader, $downloadResult, $installer, +$installResult); }

According to the Microsoft docs1, one would assign the UpdateColl to Updates (as specified above as $installer->{Updates} = $updatecoll;), but it doesn't take. The dump shows that Updates is undef.

Does anyone have any idea what it is I'm doing wrong?

Here is the test.pl that I'm using:

use Win32::WindowsUpdate; my $wu = Win32::WindowsUpdate->new; $wu->install( '09569688-db5d-422b-965d-aac88486fae4', '60b990a0-6efa-47be-8f5a-7df2c402583e', );
And this is the output:
H:\Projects\Win32-WindowsUpdate\lib>perl test.pl Adding 09569688-db5d-422b-965d-aac88486fae4 February 2007 CardSpace Up +date for Windows XP (KB925720) to collection Adding 60b990a0-6efa-47be-8f5a-7df2c402583e Windows XP Service Pack 3 +(KB936929) to collection Updates to install: 2 $VAR1 = bless( { 'Item' => undef, '_NewEnum' => undef, 'Count' => 2, 'ReadOnly' => 0 }, 'Win32::OLE' ); $VAR2 = bless( { 'ClientApplicationID' => '', 'IsForced' => 0, 'Priority' => 3, 'Updates' => undef }, 'Win32::OLE' ); $VAR3 = undef; $VAR4 = bless( { 'ClientApplicationID' => '', 'IsForced' => 0, 'parentWindow' => undef, 'Updates' => undef, ## this is the trouble spot 'IsBusy' => 0, 'AllowSourcePrompts' => 0, 'RebootRequiredBeforeInstallation' => 0, 'ForceQuiet' => 1 }, 'Win32::OLE' ); $VAR5 = undef;

1 http://msdn.microsoft.com/en-us/library/aa387101(VS.85).aspx


I'm a Linux user. You wouldn't know it since I mostly ask Windows questions. Whee.
If you want to do evil, science provides the most powerful weapons to do evil; but equally, if you want to do good, science puts into your hands the most powerful tools to do so.
- Richard Dawkins

Replies are listed 'Best First'.
Re: Windows Update via Perl (Win32::OLE problem)
by jand (Friar) on Feb 19, 2009 at 00:44 UTC
    You may want to check if using LetProperty() does the right thing for you:
    $installer->LetProperty("Updates", $updatecoll);

    The hash reference syntax in Perl corresponds to the Set assignment in VB. There only is a difference between Let and Set when you are assigning object references.

      Too bad I didn't read your message before I implemented something in VBScript (via Inline::WSC). I'll undo that and use LetProperty as it works great (it seems). Thanks!


      I'm a Linux user. You wouldn't know it since I mostly ask Windows questions. Whee.
      If you want to do evil, science provides the most powerful weapons to do evil; but equally, if you want to do good, science puts into your hands the most powerful tools to do so.
      - Richard Dawkins