SMS texting via Powershell

I have a script that collects data and serial number information from a workstation. It also emails me with an attachment of the collected data. I want to incorporate an SMS text message. Below is the current script I'm using.

#Clear the screen
cls

#Create Folder
$MyFolder = New-Item -Force -Path 'c:\Inventory' -ItemType Directory

#Change Directory
Set-Location -Path $MyFolder

#Create File
$text | Set-Content "$env:computername.txt"

#Write Asset Tag Number to file
"Asset Tag: "+ (Get-WmiObject win32_bios).SerialNumber | out-file "$env:computername.txt"

#Write Computer Name to file
"Computer Name: "+$env:COMPUTERNAME | out-file "$env:computername.txt" -Append

#Write Monitor Serial Numbers to file
Get-WmiObject WmiMonitorID -Namespace root\wmi|Select @{n="Make_Model"
;e={[System.Text.Encoding]::ASCII.GetString($_.UserFriendlyName -ne 00)}},@{n="Serial Number"
;e={[System.Text.Encoding]::ASCII.GetString($_.SerialNumberID -ne 00)}}|
out-file "$env:computername.txt" -Append

#get default printer
gwmi win32_printer | where { $_.Default } | out-file "$env:computername.txt" -Append


#Open Notepad
#start notepad "$env:computername.txt"

#Email the file
$Outlook = New-Object -ComObject Outlook.Application
$Mail = $Outlook.CreateItem(0)
$Mail.To = "dbrown@jhoustonhomes.com"
$Mail.Subject = "Monitor-Inventory"
$Contacts = Get-Content "$env:computername.txt"
$File = "$env:computername.txt"
$Mail.Body = $Contacts | Out-String
$Mail.Send()

#echo $Contacts
#echo $File

Parents
No Data
Reply
  • Email and SMS use the same sort of transport. You can send a text to any phone number you know, as long as you know the providers domain that phone number is on.

    There are many articles and samples of how to send SMS via say MS Outlook all over the web.

    A quick web search using ...

    'send sms via outlook'

    ...would get you that info.

    For Example:
    How to Send Text Messages Using Microsoft Outlook
    https://www.techwalla.com/articles/how-to-send-text-messages-using-microsoft-outlook

    Using an Outlook Rule to Send Email to SMS
    https://www.thebalancesmb.com/using-an-outlook-rule-to-send-email-to-sms-2867329

    Videos:
    https://www.bing.com/videos/search?q=send+sms+via+outlook&qpvt=send+sms+via+outlook&FORM=VDRE

    PowerShell's Send-MailMessage
    https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/send-mailmessage?view=powershell-6

    # Get a list of all functions for the specified name
    Get-Command -Name '*MailMessage*' -CommandType Function |
    Out-GridView -PassThru -Title 'Available named functions'

    # Get a list of all commandlets for the specified name
    Get-Command -Name '*MailMessage**'  -CommandType Cmdlet |
    Out-GridView -PassThru -Title 'Available named cmdlet'

    # get function / cmdlet details
    Get-Command -Name Send-MailMessage -Syntax
    (Get-Command -Name Send-MailMessage).Parameters.Keys

    Get-help -Name Send-MailMessage -Full
    Get-help -Name Send-MailMessage -Online
    Get-help -Name Send-MailMessage -Examples

    Send-MailMessage -To "User01 <user01@example.com>" -From "User02 <user02@example.com>" -Subject "Test mail" 
    Send-MailMessage -From "User01 <user01@example.com>" -To "User02 <user02@example.com>", "User03 <user03@example.com>" -Subject  
    Send-MailMessage -To "User01 <user01@example.com>" -From "ITGroup <itdept@example.com>" -Cc "User02 <user02@example.com>" -bcc  


    or the .Net SMTPClient (without the need for Outlook at all) can be used for the same thing.

    A simple search using the string...

    'powershell send output as email'

    ... will get you that info.


    It's In the Mail Part 1: Sending PowerShell Data via E-Mail
    https://mcpmag.com/articles/2013/06/04/in-the-mail-part-1.aspx


    How to Send SMTP Email Using PowerShell
    • Part 1 – How to Send SMTP Email Using PowerShell
    • Part 2 – How to Add a Message Body to Emails Sent from Scripts
    • Part 3 – How to Add a HTML Message Body to Emails Sent from Scripts
    • Part 4 – How to Create Formatted HTML Output from Scripts
    https://practical365.com/exchange-server/powershell-how-to-send-email

    FYI --- Just a few edification items below, well, maybe a bunch.

    No real reason to send to a file, you can just store in an object and send object output

    Don't use aliases in scripts ...

    http://powershell-guru.com/powershell-best-practice-1-use-full-cmdlet-name-not-alias

    ... also understand this when using them in general.

    The same goes for parameter names. Aliases are really good for interactive keyboard cowboy stuff, but not in scripts.
    Just becasue you are good at them, does not mena those who follow you, who have to maintain your code or to whom you may share code with, understand them or want to at all.


    Nasty gotcha: Powershell aliases that match commands you might want to run
    https://devblogs.microsoft.com/oldnewthing/?p=97235

    Avoid string concatenation whenever possible as it leads to unexpect results.

    Simply proper quote the strings or leverage iteroplation / sub-expressions.

    http://www.powershellish.com/blog/2014-12-09-strings-expansion
    http://maikkoster.com/cim-vs-wmi-cmdlets-the-top-reasons-i-changed
    https://powershellexplained.com/2017-01-13-powershell-variable-substitution-in-strings
    https://devblogs.microsoft.com/powershell/variable-expansion-in-strings-and-here-strings
    https://devops-collective-inc.gitbook.io/the-big-book-of-powershell-gotchas/dont-concatenate-strings


    # this
     "Computer Name: $env:COMPUTERNAME"
    # or this
     "Computer Name: $($env:COMPUTERNAME)"

     "Asset Tag: $((Get-WmiObject -Class Win32_bios).SerialNumber)"

     "Asset Tag: $((Get-CimInstance -ClassName Win32_bios).SerialNumber)"


    Note, that calling monitor info alos brings back the computername that monitor
    is on, so, no need for that seperate computer name effort.

    Also, Get-Cim* is the new hotness vs Get-Wmi*

    https://devblogs.microsoft.com/scripting/should-i-use-cim-or-wmi-with-windows-powershell
    https://richardspowershellblog.wordpress.com/2013/03/24/wmi-vs-cim
    https://richardspowershellblog.wordpress.com/2013/03/24/wmi-vs-cim
    http://maikkoster.com/cim-vs-wmi-cmdlets-speed-comparison
    http://maikkoster.com/cim-vs-wmi-cmdlets-the-top-reasons-i-changed

    I still find reasons, personally to use WMi of CIM due to speed and what is returned.


    You can also, just use the normal PowerShell object construction.

    So, this ..

    Get-WmiObject WmiMonitorID -Namespace root\wmi |
    Select @{Name ='Make_Model';Expression = {[System.Text.Encoding]::ASCII.GetString($PSItem.UserFriendlyName -ne 0)}},
     @{Name = 'Serial Number';Expression={[System.Text.Encoding]::ASCII.GetString($PSItem.SerialNumberID -ne 0)}}

     # Becomes, this...

    Get-CimInstance -Namespace 'root\wmi' -ClassName wmimonitorid |
    foreach {
     New-Object -TypeName psobject -Property @{
            MakeModel = ([System.Text.Encoding]::ASCII.GetString($PSItem.UserFriendlyName -ne 0))
            SerialNumber = ([System.Text.Encoding]::ASCII.GetString($PSItem.SerialNumberID -ne 0))
        }
    }

    # and so on


    All that being said, depending on what PS version you are on, there is a cmdlet for this main computer info stuff.
    Guess what it is called and it's designed to get you the same info that systeminfo.exe provides.


    # Get a list of all functions for the specified name
    Get-Command -Name '*Computer*' -CommandType Function |
    Out-GridView -PassThru -Title 'Available named functions'

    # Get a list of all commandlets for the specified name
    Get-Command -Name '*Computer**'  -CommandType Cmdlet |
    Out-GridView -PassThru -Title 'Available named cmdlet'

    # get function / cmdlet details
    Get-Command -Name Get-ComputerInfo -Syntax
    (Get-Command -Name Get-ComputerInfo).Parameters.Keys
    Get-help -Name Get-ComputerInfo -Full
    Get-help -Name Get-ComputerInfo -Online
    Get-help -Name Get-ComputerInfo -Examples

    # Assign to a variable and dot as needed
    $ComputerSpecs = Get-ComputerInfo
    $ComputerSpecs.CsName
    $ComputerSpecs.OsName
    $ComputerSpecs.BiosSeralNumber
    $ComputerSpecs.CsModel

    # So, you could just do this, and sending this output direclty.
    Clear-Host
    $ComputerDetails = New-Object -TypeName psobject -Property @{
        ComputerName   = $env:COMPUTERNAME
        AssetTag       = $((Get-CimInstance -ClassName Win32_Bios).SerialNumber)
        DefaultPrinter = $(
                            (Get-CimInstance -ClassName Win32_Printer |
                            Where-Object { $PSItem.Default }).Name
                          )
    }

    $MonitorDetails = Get-CimInstance -Namespace 'root\wmi' -ClassName wmimonitorid |
    foreach {
     New-Object -TypeName psobject -Property @{
            MakeModel      = ([System.Text.Encoding]::ASCII.GetString($PSItem.UserFriendlyName -ne 0))
            MonitorSerial  = ([System.Text.Encoding]::ASCII.GetString($PSItem.SerialNumberID -ne 0))
        }
    }

    $ComputerDetails

    # Results

    DefaultPrinter         ComputerName AssetTag
    --------------         ------------ --------
    Microsoft Print to PDF LP70         PC0AEEDG


    $MonitorDetails

    # Results

    MakeModel     MonitorSerial
    ---------     -------------
                 0           
    ASUS VE278    B7LMTF125646
    ASUS VE278    E8LMTF076033
    MB168B+       ACI1642


    # Or this
    Clear-Host
    Get-CimInstance -Namespace 'root\wmi' -ClassName wmimonitorid |
    foreach {
     New-Object -TypeName psobject -Property @{
            ComputerName   = $env:COMPUTERNAME
            AssetTag       = $((Get-CimInstance -ClassName Win32_Bios).SerialNumber)
            DefaultPrinter = $((Get-CimInstance -ClassName Win32_Printer | Where-Object { $PSItem.Default }).Name)
            MakeModel      = ([System.Text.Encoding]::ASCII.GetString($PSItem.UserFriendlyName -ne 0))
            MonitorSerial  = ([System.Text.Encoding]::ASCII.GetString($PSItem.SerialNumberID -ne 0))
        }
    } | Format-Table -AutoSize


    # Results


    DefaultPrinter         MonitorSerial ComputerName AssetTag MakeModel   
    --------------         ------------- ------------ -------- ---------   
    Microsoft Print to PDF 0             LP70         PC0AEEDG            
    Microsoft Print to PDF B7LMTF125646  LP70         PC0AEEDG ASUS VE278  
    Microsoft Print to PDF E8LMTF076033  LP70         PC0AEEDG ASUS VE278  
    Microsoft Print to PDF ACI1642       LP70         PC0AEEDG MB168B+

Children
No Data