Welcome to MSDN Blogs Sign in | Join | Help

Generate and run PowerShell scripts dynamically

In my prior post Use new XML Features of VB to generate dynamic scripts and text files , we generated a simple batch file. It’s difficult to modify the registry or manipulate a COM object

 

PowerShell scripts allow you to manipulate files, registry and COM objects, using a uniform object manipulation metaphor. For example, you can use CD and DIR at a command prompt to navigate the file system, the registry and certificate store too.

 

Here's a simple sample navigating the registry of Fox: (user typed text in this color)

 

Windows PowerShell

Copyright (C) 2006 Microsoft Corporation. All rights reserved.

 

PS C:\Documents and Settings\calvinh> cd hkcu:

PS HKCU:\> cd Software

PS HKCU:\Software> cd HKCU:\Software\Microsoft\VisualFoxPro

PS HKCU:\Software\Microsoft\VisualFoxPro> dir

 

 

   Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\VisualFoxPro

 

SKC  VC Name                           Property

---  -- ----                           --------

  5   0 9.0                            {}

 

 

PS HKCU:\Software\Microsoft\VisualFoxPro> cd 9.0

PS HKCU:\Software\Microsoft\VisualFoxPro\9.0> dir

 

 

   Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\VisualFoxPro\9.0

 

SKC  VC Name                           Property

---  -- ----                           --------

  0   1 ChooseColor                    {(default)}

  0   8 Coverage                       {FrmzoomHeight, FrmzoomTop, FrmzoomWidth, FrmzoomLeft...}

  0   7 Desktop                        {Zoomed, Row, Column, Height...}

  0   0 Fonts                          {}

  4 192 Options                        {LastProject, TALK, StatusBar, NOTIFY...}

 

 

PS HKCU:\Software\Microsoft\VisualFoxPro\9.0>

 

 

 

 

 

This PowerShell script sample modifies the setting of SET SAFETY by directly manipulating the registry, then forcing VFP to reread the registry settings using SYS(3056)

 

ERASE d:\t.txt

*http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx

*Set-ExecutionPolicy remotesigned

SET SAFETY OFF

?"Safety before",SET("Safety")

TEXT TO myvar

#This is a sample powershell script

#get-process > d:\t.txt

#get-psdrive > d:\t.txt

#CD HKCU:\Software\Microsoft\VisualFoxPro\9.0

#get-Item * >> d:\t.txt

#can specify path to registry

#get setting of all reg keys starting with "s":

#get-ItemProperty -path registry::HKCU\Software\Microsoft\VisualFoxPro\9.0\Options s* >> d:\t.txt

#get-ItemProperty -path registry::HKCU\Software\Microsoft\VisualFoxPro\9.0\Options safety >> d:\t.txt

set-ItemProperty -path registry::HKCU\Software\Microsoft\VisualFoxPro\9.0\Options safety ON >> d:\t.txt

 

ENDTEXT

STRTOFILE(myvar,"d:\Myscript.ps1")

! powershell d:\Myscript

?STRCONV(SUBSTR(FILETOSTR("d:\t.txt"),3),6)     && convert from Unicode, remove ByteOrderMark

SYS(3056)   && Force VFP to reread registry

 

?"Safety After: ",SET("safety")

SET SAFETY OFF    && restore value

 

 

You can even create a VFP COM Object from within a PowerShell script and invoke its methods: (using my favorite VFP COM Object "t1.c1")

 

Here's a PowerShell script sample that creates an instance of Excel, and passes it to the VFP COM object for further manipulation: The hardest part of this code was trying to figure out how to close Excel without saving changes!

 

PowerShell variables start with “$”, comments start with “#”

 

SET SAFETY OFF 

sOutputFile="d:\t.txt"

ERASE (sOutputFile)

ERASE (sOutputFile)

TEXT TO myvar  TEXTMERGE

#create Excel

$oExcel = New-Object -ComObject Excel.Application

#create VFP COM Object

$oVFP = New-Object -ComObject t1.c1

#Pass Excel to VFP object

$oVFP.MyDoCmd("p2.Visible=1",$oExcel,0,0,0)

#Get the name of the object

$oVFP.MyEval("p2.name",$oExcel,0,0,0) >> <<sOutputFile>>

#Add a workbook

$oVFP.MyDoCmd("p2.Workbooks.Add",$oExcel,0,0,0)

$pv="PowerShell variable"

#Change the 1st cell's value to a combination of VFP and Powershell vars

$oVFP.MyDoCmd("p2.Cells(1,1).value='Hi from VFP '+p3",$oExcel,$pv,0,0)

$oVFP.MyDoCmd("DECLARE integer MessageBoxA IN WIN32API integer,string,string,integer",0,0,0,0)

$oVFP.MyEval("MessageBoxA(0,'Hi From VFP inside PowerShell','',0)",0,0,0,0)

#Close Excel workbook without saving!

$oVFP.MyDoCmd("p2.ActiveWorkbook.Close(.f.)",$oExcel,0,0,0)

$oVFP.MyDoCmd("p2.Visible=0",$oExcel,0,0,0)

$oVFP.MyDoCmd("p2.Quit",$oExcel,0,0,0)

 

ENDTEXT

STRTOFILE(myvar,"d:\Myscript.ps1")

! powershell d:\Myscript

IF FILE(sOutputFile)

      ?STRCONV(SUBSTR(FILETOSTR(sOutputFile),3),6)    && convert from Unicode, remove ByteOrderMark

ENDIF

 

 

 

You can do this from VB using the new XML features (Use new XML Features of VB to generate dynamic scripts and text files )

 

Module Module1

 

    Sub Main()

        Dim sOutputFile = "d:\t.txt"

        Dim sScriptFile = "d:\t.ps1"

        If My.Computer.FileSystem.FileExists(sOutputFile) Then

            My.Computer.FileSystem.DeleteFile(sOutputFile)

        End If

        Dim PowerShellScriptXML = <myxml>

#create Excel

$oExcel = New-Object -ComObject Excel.Application

#create VFP COM Object

$oVFP = New-Object -ComObject t1.c1

#Pass Excel to VFP object

$oVFP.MyDoCmd("p2.Visible=1",$oExcel,0,0,0)

#Get the name of the object

$oVFP.MyEval("p2.name",$oExcel,0,0,0) >> <%= sOutputFile %>

#Add a workbook

$oVFP.MyDoCmd("p2.Workbooks.Add",$oExcel,0,0,0)

$pv="PowerShell variable"

#Change the 1st cell's value to a combination of VFP and Powershell vars

$oVFP.MyDoCmd("p2.Cells(1,1).value='Hi from VFP '+p3",$oExcel,$pv,0,0)

$oVFP.MyDoCmd("DECLARE integer MessageBoxA IN WIN32API integer,string,string,integer",0,0,0,0)

$oVFP.MyEval("MessageBoxA(0,'Hi From VFP inside PowerShell','',0)",0,0,0,0)

#Close Excel workbook without saving!

$oVFP.MyDoCmd("p2.ActiveWorkbook.Close(.f.)",$oExcel,0,0,0)

$oVFP.MyDoCmd("p2.Visible=0",$oExcel,0,0,0)

$oVFP.MyDoCmd("p2.Quit",$oExcel,0,0,0)

                 </myxml>

        Console.WriteLine(PowerShellScriptXML.Value)

        My.Computer.FileSystem.WriteAllText(sScriptFile, PowerShellScriptXML.Value, False, Text.Encoding.ASCII)

        Dim proc = System.Diagnostics.Process.Start("PowerShell", sScriptFile)

        proc.WaitForExit()

        Dim ss = My.Computer.FileSystem.ReadAllText(sOutputFile)

        MsgBox("Proc Done " + ss)

    End Sub

 

End Module

 

 

 

End of code

 

See also

How to create the general purpose "T1.c1" server: Blogs get 300 hits per hour: Visual FoxPro can count.

 

Published Monday, October 08, 2007 12:13 PM by Calvin_Hsia

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Embed Code and Avoid Underscores in Your Multiline Strings

Tuesday, October 23, 2007 3:23 PM by Beth Massi - Sharing the goodness that is VB

One of the things I most dearly missed from FoxPro when I moved to VB.NET was the ability to easily dump

# Calvin Hsia s WebLog Generate and run PowerShell scripts dynamically | Uniform Stores

# re: Generate and run PowerShell scripts dynamically

Tuesday, October 13, 2009 12:17 PM by Mike McCann

Just used the PowerShell ISE for the first time.  No Intellisense at the command line?? Not even MDI.  Why couldn't they "walk down the hall" to see Calvin before they released this antique.  Obviously no peer review at that shop.

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker