PoSH & VBS working hand in hand

Author Message
turranx

  • Total Posts : 59
  • Scores: 0
  • Reward points : 0
  • Joined: 2/7/2006
  • Location: Cincinnati, OH
  • Status: offline
PoSH & VBS working hand in hand Wednesday, October 08, 2008 6:58 AM (permalink)
0
Our environment is migrating from Windows 2000/2003/XP to Windows 2008/Vista.  When you make the jump from any of the older server or desktop OSs to the newer server and desktop OSs (Vista & WS2008), some stuff breaks.  The broken functionality that is causing me a lot of pain is email.  The CDO messaging component that I've relied upon for 5 years is missing from Vista.

This works in 2000/2003/XP but not Vista:
     Dim objEmail
     Set objEmail = CreateObject("CDO.Message")
    
     objEmail.From = strFrom
     objEmail.To = strRecipients
     objEmail.Subject = strSubject
     objEmail.Textbody = strBody
     objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
     objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "<mail server>"
     objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
     objEmail.Configuration.Fields.Update
     objEmail.Send
     Set objEmail = Nothing
 


This works in Vista because PowerShell is installed in Vista:
     $msg = New-object System.Net.Mail.MailMessage 'MessageSender@live.com', 'MessageRecipient@Go.org', 'Message Subject', 'Message Body';
     $client = New-object System.Net.Mail.SmtpClient 'Mail_Server.Live.com';
     $client.UseDefaultCredentials = $true;
     $client.send($msg);
 


But can what do you do if you want to keep using the same VB Scripts (because they work) and replace the dead components?  You could try something like this:
     Dim objShell
     Dim exitcode
     Dim strFrom
     Dim strRecipients
     Dim strSubject
     Dim strBody
     Dim strMailServer
 
     Set objShell = WScript.CreateObject("WScript.shell")
     strFrom = "MessageSender@Live.com"
     strRecipients = "MessageRecipient@Go.org"
     strSubject = "Subject"
     strMailServer = "Mail_Server.Live.com"
     strBody = "Blah Blah Back Schleep, Have you any Woolski?"
     strBody = Replace(strBody,"'","`")
     
     exitcode = objShell.Run("Powershell.exe -NoProfile -command ""& {$msg = New-object System.Net.Mail.MailMessage " & _
                "'" & strFrom & "','" & strRecipients & "','" & strSubject & "','" & strBody & "';" & _
                "$client = New-object System.Net.Mail.SmtpClient '" & strMailServer & "';" & _
                "$client.UseDefaultCredentials = $true;$client.send($msg);}""")
 

But the problem with this (above) code is that once your body reaches a certian character limit, the objShell.Run() call fails.  So what else to do?


What about using a file to hold the contents of the body?
     Dim objShell
     Dim exitcode
     Dim strFrom
     Dim strRecipients
     Dim strSubject
     Dim strBody
     Dim strMailServer
     Dim objFSO
     Dim objEmail_Body_File
     Dim strEmail_Body_File_Full_Path
     
     Set objShell = WScript.CreateObject("WScript.shell")
     Set objFSO = Wscript.CreateObject("Scripting.FileSystemObject")
     strEmail_Body_File_Full_Path = objShell.ExpandEnvironmentStrings(objShell.Environment("User")("TEMP")) & "\" & objFSO.GetTempName
     Set objEmail_Body_File = objFSO.CreateTextFile(strEmail_Body_File_Full_Path, True)
     
     strFrom = "MessageSender@Live.com"
     strRecipients = "MessageRecipient@Go.org"
     strSubject = "Subject"
     strMailServer = "Mail_Server.Live.com"
     strBody = "Blah Blah Back Schleep, Have you any Woolski?"
     strBody = Replace(strBody,"'","`")
     
     objEmail_Body_File.Write strBody
     objEmail_Body_File.Close
     WScript.Sleep 2000  'The pause is necessary to allow the file system to catch up before handing it over to PoSH
     Set objEmail_Body_File = Nothing
     
     exitcode = objShell.Run("Powershell.exe -NoProfile -command ""& {$msg = New-object System.Net.Mail.MailMessage " & _
                "'" & strFrom & "','" & strRecipients & "','" & strSubject & "'," & _
                "$([String]::Join('" & vbcrlf & "',$(get-content " & strEmail_Body_File_Full_Path & ")));" & _
                "$client = New-object System.Net.Mail.SmtpClient '" & strMailServer & "';" & _
                "$client.UseDefaultCredentials = $true;$client.send($msg);}""")
 

This works* but relies upon somewhere to write on the file system.  I'd really like to move away from using files to transfer the data between scripting languages.  You'll notice an extra line in the PoSH command.  When 'get-content' reads a file, it doesn't return a string.  It returns an object that contains an array of strings.  These strings were created on Carridge Return / Line Feed markers.  It's the equivalent of 'arrLines = Split(strEmailBody,VBCRLF)' in VBS.  If you pass the PoSH object $msg this array of strings, it fails.  So you have to Join it back together using the PoSH command '[String]::Join()'.

*This doesn't always work. While it does work on my own Vista box, it fails on a co-workers Vista box with a "System cannot find the file specified" error.  I've not yet had the chance to sit down and figure out why the code breaks on his workstation.


What other options do we have?  What about an objShell.Exec() attempt?  To keep it simple, lets not even worry about sending an email.  Lets instead center on getting commands into and out of an objShell.Exec shell object.
     Dim objExec
     Dim objStdIn
     Dim objStdOut
     
     Set objExec = objShell.Exec("%comspec% /c Powershell.exe")
     Set objStdIn = objExec.StdIn
     Set objStdOut = objExec.StdOut
     WScript.Sleep 1000
     Wscript.Echo objStdOut.ReadAll  'Hangs here after dumping PoSH script environment information to the screen
     objStdIn.Write("Exit")
     objExec.Terminate
     WScript.Quit
 

You can see from my comment in the code above she no-workie.  I have to kill the PowerShell.exe executable in Task Manager before the script will continue.  When it does continue, it obviously errors out since the shell instance running inside objExec is no longer "alive".  If I were to take out the command 'Wscript.echo objStdOut.ReadAll' entierly, it would go on to 'objStdIn.Write("Exit")' and hang again.  I had hoped that with this code I would be able to open a shell, run PoSH inside of it then close it down gracefully.  Unfortunately it hangs like toilet paper on trees in late October.


So this is where I stand: I can use objShell.Run() but don't like having to pass the body of an email from one language to the next through the file system.  Does anyone have any ideas?
Microsoft Windows 2000 Scripting Guide - The best book for newbie scripters
http://www.myspace.com/Evil__Overlord
 
#1
    SAPIENScripter

    • Total Posts : 283
    • Scores: 2
    • Reward points : 0
    • Joined: 11/1/2006
    • Location: SAPIEN Technologies
    • Status: offline
    RE: PoSH & VBS working hand in hand Wednesday, October 08, 2008 9:44 AM (permalink)
    0
    A lot of scripting things change and break in Vista. In some cases you may be better off rewriting scripts that will run on Vista. PowerShell is certainly a viable alternative, but there are many parts you need to get right, in addition to command syntax.  I'd suggest starting from scratch using the PowerShell paradigm, which takes some getting used to coming from the VBScript world.  Is there a particular task you'd like to see done in PowerShell?
    Jeffery Hicks
    Windows PowerShell MVP
    SAPIEN Technologies - Scripting, Simplified. www.SAPIEN.com

    Follow Me: http://www.twitter.com/JeffHicks
     
    #2
      turranx

      • Total Posts : 59
      • Scores: 0
      • Reward points : 0
      • Joined: 2/7/2006
      • Location: Cincinnati, OH
      • Status: offline
      RE: PoSH & VBS working hand in hand Wednesday, October 08, 2008 1:24 PM (permalink)
      0

      ORIGINAL: SAPIENScripter

      I'd suggest starting from scratch using the PowerShell paradigm, which takes some getting used to coming from the VBScript world.  Is there a particular task you'd like to see done in PowerShell?


      This email problem is a small component of a much larger script (several thousand lines).  Because my day is full already, the quickest way to meet my goals is to get PoSH working with VBS during this transition period.  Then when I have more time I'll be able to slowly phase out VBS in favor of PoSH.  Starting from scratch is not an option at this moment in time.

      See a particular task done in PoSH?  What do you mean?  Like an example of PoSH-only code that works that fits my needs?  Nope, not at this time.  But I do appreciate your time and effort.
      Microsoft Windows 2000 Scripting Guide - The best book for newbie scripters
      http://www.myspace.com/Evil__Overlord
       
      #3
        SAPIENScripter

        • Total Posts : 283
        • Scores: 2
        • Reward points : 0
        • Joined: 11/1/2006
        • Location: SAPIEN Technologies
        • Status: offline
        RE: PoSH & VBS working hand in hand Wednesday, October 08, 2008 10:11 PM (permalink)
        0
        Your effort was a little overwhelming and I wasn't sure what you wanted to accomplish. You should be able to write a PowerShell script to do certain tasks and execute from VBS using the Exec or Run method:

        powershell -nologo -command "& (c:\scripts\myscript.ps1}"

        While you can pass parameters to your script you won't be able to share variables between the two unless you write them to a shared space like the registry or a file. 

        From a command prompt type powershell /? to see how you would execute a powershell command or script.
        Jeffery Hicks
        Windows PowerShell MVP
        SAPIEN Technologies - Scripting, Simplified. www.SAPIEN.com

        Follow Me: http://www.twitter.com/JeffHicks
         
        #4

          Online Bookmarks Sharing: Share/Bookmark

          Jump to:

          Current active users

          There are 0 members and 1 guests.

          Icon Legend and Permission

          • New Messages
          • No New Messages
          • Hot Topic w/ New Messages
          • Hot Topic w/o New Messages
          • Locked w/ New Messages
          • Locked w/o New Messages
          • Read Message
          • Post New Thread
          • Reply to message
          • Post New Poll
          • Submit Vote
          • Post reward post
          • Delete my own posts
          • Delete my own threads
          • Rate post

          2000-2012 ASPPlayground.NET Forum Version 3.9