blog.powershell.no

On Windows PowerShell and other admin-related topics

Send text messages (SMS) using Windows PowerShell

In Microsoft Office Outlook there is an add-in called Microsoft Outlook SMS Add-in (MOSA), which provides the ability to send text messages (SMS). MOSA is builtin to Outlook 2010, and are available as a plugin for Outlook 2003 and 2007 here.

On the Microsoft Office Online Help you can find guidance on how to set up the service account and sending a text message. To find the necessary settings for your mobile service provider, go here.

I looked into the COM-object for Outlook, and it turned out to be rather easy to use this API to send text messages from MOSA.
Based on that I created an Advanced function in Windows PowerShell v2 called Send-SMSMessage.

To define the function you can either paste it directly into your session, save it as a ps1 script-file and dot source it, put it into your profile or into a module.

When that is accomplished you can find usage information using the consistent Get-Help cmdlet:

image

Sample usage:

image

The function checks if Outlook are installed, and breaks out with a warning if not:

image

It also checks to see if an account are configured for Text Messaging (SMS):

image

Any errors related to service availabilty, correct phonenumber format and so on are handled by the SMS Add-in itself. These error messages appear in the Outlook inbox:

image

The function is tested from Outlook 2010 only, but should work from 2003 and 2007 also when MOSA is installed.

Since the function accepts ValueFromPipeline and ValueFromPipelineByPropertyName you can use it in conjunction with e.g. the Active Directory cmdlets for Windows PowerShell.  A given example of this retrieves all users from Active Directory with a derfined mobilephone number and sends them an SMS with their username:

image

Another practical usage scenario I can think of is combining the Send-SMSMessage function with user provisioning, sending the new user it`s new username and password.
Feel free to come up with more usage scenarios in the comment field below.

Bonus tips

  • You can also send MMS messages using the Outlook COM-object. To do this, use “olMobileItemMMS” instead of “olMobileItemSMS” in the following line: $NewMessage = $outlook.CreateItem(“olMobileItemMMS”). You should also look into the other properties for MMS messages, like the Attachment-property.
  • If you got more than one account configured for text messaging, you can use the SendUsingAccount-property to define which account to send from.
  • If you use the Norwegian mobile service provider Telenor, the “Service Provider URL” in the account settings is https://telenormobil.no/smapi/services/omsv3_service
Advertisements

July 21, 2010 - Posted by | Active Directory management, Microsoft Outlook, Scripting, Windows PowerShell | , ,

10 Comments »

  1. Just wondering, why would one want to use powershell to send a text message if they have outlook installed already ?

    I mean, powershell is useful – no doubt, but isn’t microsoft trying to mimick the NIX command line ? for after so many years promoting and building upon a GUI.

    Suddenly everyone is talking just about powershell 🙂

    I read your blog almost twice in a week but I am still unaware of the benefits of “Sending an SMS via Powershell” which itself is relying on MS Outlook ?

    Please enlighten, as I have seen posts on numerous blogs which are talking about using powershell for some tasks which are better done via the GUI.

    Kind Regards

    Comment by Justwondering | July 27, 2010 | Reply

  2. Thanks for reading my blog and sharing your thoughts on this topic 🙂

    I agree that every GUI feature in Windows might not be feasible in Windows PowerShell, but the idea that everything should be based on an automation engine is a good thing in my opinion. A thing that might be completely irrelavant to automate for one person might be relevant for others.

    Regarding the specific topic on automating the SMS-feature in Outlook using PowerShell I agree that it doesn`t seem logic to transfer this to the commandline. However, this wasn`t my main purpose when writing this PowerShell function. Like I gave an example on, I see some practical use of this function in an Active Directory user provisioning script (sending the new user it`s new username and password on SMS).
    For IT-related situations, I guess there are several other scenarios where sending Active Directory users info on SMS.

    Leveraging the Outlook COM API might not be the best solution for automating the sending of SMS messages, however, it might be a fast and easy solution for SMB environments 🙂

    Comment by Jan Egil Ring | July 27, 2010 | Reply

  3. […] Use PowerShell to send SMS messages […]

    Pingback by Episode 120 – Alex Riedel on PrimalScript and Visual PowerShell « PowerScripting Podcast | August 2, 2010 | Reply

  4. I met a problem. I modified your scripts to enable sending a MMS, it works well. But i want to run these scripts remotely on another computer by using invoke-command, like this(the remote computer’s PowerShell execution policy had been set as ‘Unrestricted’):
    invoke-command -computer $computerName -credential $credentialInfo -scriptblock {….}
    There will be a few errors when scripts running in the braces(I believed the logon method must be invoke when runnting scripts in braces), could you please help me to check how to fix the errors?

    The scripts are as follows:
    $ret = invoke-command -computer $computerName -Credential $credential -scriptblock {
    param(
    [string]$messageContent,
    [string]$omsSmsRecipient
    )

    # Check whether Outlook is installed
    if (-not (Test-Path “HKLM:\Software\Microsoft\Windows\CurrentVersion\App Paths\OUTLOOK.EXE”)) {
    Write-Warning “Outlook is not installed. The message was not sent.”
    return $false
    }

    Write-Host “Outlook is installed.”

    # Create Outlook application
    $outlookApp = New-Object -ComObject outlook.application
    if ($outlookApp -eq $null)
    {
    Write-Host “Create Com Object Outlook.application failed.”
    return $false
    }

    Write-Host “Create Com Object Outlook.application success.”

    # Declare namespace and current user
    $nameSpace = $null
    $curUser = $null

    #$curProfileName = $outlookApp.Session.CurrentProfileName
    #$curProfileName

    # Logon on outlook account
    $curUser = $outlookApp.Session.CurrentUser
    Write-Host “Get current user.”
    if ($curUser -eq $null)
    {
    Write-Warning “User not logon on.”

    $nameSpace = $outlookApp.GetNamespace(“MAPI”)
    if ($nameSpace -eq $null)
    {
    Write-Warning “Namespace is null.”
    return $false
    }
    else
    {
    Write-Warning “Namespace is not null.”
    $nameSpace.Logon($null, $null, $false, $false)
    }

    return $false

    $curUser = $outlookApp.Session.CurrentUser
    if ($curUser -eq $null)
    {
    Write-Warning “User logon on failed.”
    return $false
    }
    }

    Write-Host “Current user is valid.”
    return $false

    # Check Outlook version
    if ($outlookApp.Version.StartsWith(“14”) -eq $false)
    {
    Write-Warning “Outlook version error, only Outlook 2010 is supported.”
    return $false
    }

    # Check wheter an other account (SMS or MMS) are set up in Outlook
    if (-not (($outlookApp.Session.Accounts | Where-Object {$_.AccountType -eq “5”} | Measure-Object).Count -gt 0)) {
    Write-Warning “Outlook are installed, but no accounts are configured for SMS or MMS. The message was not sent.”
    return $false
    }

    # Check if Outlook are running
    $OutlookState = Get-Process | Where-Object {$_.Name -eq “outlook”}

    # Create MMS mail item
    $mmsItem = $outlookApp.CreateItem(“olMobileItemMMS”)
    if ($mmsItem -eq $null)
    {
    #Write-Error “Create MMS Mail Item Failed.”
    Write-Warning “Create MMS Mail Item Failed.”
    return $false
    }

    # Set recipient and subject
    $mmsItem.To = $omsSmsRecipient
    $mmsItem.Subject = “Test MMS Sent From Outlook Client”;

    # Build multimedia content: text content
    $textFileName = “D:\11.txt”;
    $txtAttachment = $mmsItem.Attachments.Add($textFileName, 1);
    # Set ContentID of text content
    $txtAttachment.PropertyAccessor.SetProperty(“http://schemas.microsoft.com/mapi/proptag/0x3712001F”, “cid:Att0.txt@AB1B43B2B0594564.B94EF7ABB12B49BA”)

    # Build multimedia content: jpg content
    $jpgFileName = “D:\test.jpg”
    $jpgAttachment = $mmsItem.Attachments.Add($jpgFileName, 1);
    # Set ContentID of jpg content
    $jpgAttachment.PropertyAccessor.SetProperty(“http://schemas.microsoft.com/mapi/proptag/0x3712001F”, “cid:Att1.jpg@AB1B43B2B0594564.B94EF7ABB12B49BA”);

    # Build SMIL
    $smilXml = “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”
    $smilXml += “”

    write-host $smilXml

    # Set SMILBody
    $mmsItem.SMILBody = $smilXml

    # Send MMS
    $mmsItem.Send($true)

    # Close outlook.exe if it was not running before executing this function
    if (-not $OutlookState) {
    $outlookApp.Quit()
    }

    # Log off
    if ($nameSpace -ne $null)
    {
    $nameSpace.Logoff()
    }

    return $true

    } -argumentlist $messageContent, $omsSmsRecipient

    return $ret

    trap [exception] { $_ >> .\TriggerSendDeliverXmsMessageWithMMS.txt}

    Comment by dennis | August 23, 2010 | Reply

  5. When I submit the comments, the contents of $smilXml are missed. But it’s OK, the errors do not occurs there, and you can set $smil as follows:

    Comment by dennis | August 23, 2010 | Reply

  6. Here are the encoded xml:

    “<?xml version="1.0" standalone="yes"?>\r\n<smil>\r\n <head>\r\n <meta name="author" content="MSOfficeOlkOMS"/>\r\n <layout>\r\n <root-layout width="176" height="220" background-color="#ffffff"/>\r\n <region id="Image" left="0%" top="0%" width="100%" height="75%" fit="slice"/>\r\n <region id="Text" left="0%" top="75%" width="100%" height="25%" fit="slice"/>\r\n </layout>\r\n </head>\r\n <body>\r\n <par dur="3s">\r\n <img src="cid:Att1.jpg@AB1B43B2B0594564.B94EF7ABB12B49BA" region="Image"/>\r\n <text src="cid:Att0.txt@AB1B43B2B0594564.B94EF7ABB12B49BA" region="Text">\r\n <param name="foreground-color" value="#000000" />\r\n </text>\r\n </par>\r\n </body>\r\n</smil>”

    Comment by dennis | August 23, 2010 | Reply

  7. Could you provide the exact error message?

    Comment by Jan Egil Ring | August 23, 2010 | Reply

  8. After invoking of Logon, there will be an exception when calling “CreateItem”:
    Exception calling “CreateItem” with “1” argument(s): “Cannot create the e-mail m
    essage because a data file to send and receive messages cannot be found. Check y
    our settings in this Microsoft Outlook profile. In Microsoft Windows, click the
    Start button, and then click Control Panel. Click User Accounts, and then click
    Mail. Click Show Profiles, select this profile, and then click Propertiess.”
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    So, I invoked AddStore method to add an store with a dat file like this:
    $otherStoreDataFile = “d:\test\test.pst”
    $nameSpace.AddStore($otherStoreDataFile);
    but there will be another error:
    Exception calling “AddStore” with “1” argument(s): “The Outlook data file (.pst)
    failed to load for this session.”
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    Could you help to figure out the reason? How can I get an actual Session of Outlook? What’s the right manner to Send MMS using Powershell remotely?

    Comment by dennis | August 24, 2010 | Reply

  9. Does it work when running locally (not using Invoke-Command -computername)?
    Since outlook.exe are started in the background when loading the Outlook COM-object, it might be that some functionality doesn`t work in a remote session.
    I would suggest you submit a question regarding this over at the Scripting Guys forum at Microsoft TechNet:
    http://social.technet.microsoft.com/Forums/en/ITCG/threads

    I`m sure someone there would be able to provide assistance regarding the issue.

    Comment by Jan Egil Ring | August 24, 2010 | Reply

  10. “Does it work when running locally”
    A: Yes, it works very well, even if without invoking of logon.

    Thanks for your help! I’ll submit question to that forum.

    Comment by dennis | August 24, 2010 | Reply


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: