MSEndpointMgr

Get E-mail notification for new Application Requests

Would you like to receive an email when a new Application Request is submitted by an end-user? I’d love to and that’s the reason I created this small PowerShell script to take care of just that. The script is very basic and should be setup to run by a scheduled task on a repeating schedule, e.g. 10 minutes or whatever suits the environment. See this post on how to setup the scheduled task.

How it works

The script gets each submitted Application Request by querying WMI, more exactly the SMS_UserApplicationRequest class. It looks for objects where the CurrentState property is set to 1. For each object found, it tries to match the objects GUID property value from previous requests stored in a text file. If there’s a match, it will not send an email notification. Instead when the GUID can’t be matched to any entry in the text file, an email notification is sent with the user name, application name and comments from the submitted Application Request.

The script

If you’re looking for an alternative for this script, I highly recommend Coretech’s CTAA web application that can be found here:
https://blog.coretech.dk/kea/enabling-email-approvals-for-your-requested-applications-in-configuration-manager-2012/

#Hard-coded variables
$SiteCode = "P01"
$ComputerName = "<NetBIOSName>"
$GUIDFilePath = "C:\Scripts\GUIDList.txt"
$FilePath = "E:\Scripts"
#Get the entries from GUIDList.txt
$GetGUID = Get-Content -Path $GUIDFilePath
#Get all Application Requests with a CurrentState of "1"
$GetAppRequest = Get-WmiObject -Class SMS_UserApplicationRequest -Namespace root/SMS/site_$SiteCode -ComputerName $ComputerName | Where-Object {$_.CurrentState -like "1"} | ForEach-Object {
if ($GetGUID -contains $_.RequestGuid) {
Write-Host "Application request $($_.RequestGuid) already present"
}
else {
$appUser = $_.User
$appName = $_.Application
$appComment = $_.Comments
$Body = @"
Application request: $appName
User: $appUser
Comment: $appComment
"@ #This row can't contain any blank spaces or tabs
#Email configuration
Send-MailMessage -SmtpServer "<smtp_server_FQDN>" -From "[email protected]" -To "[email protected]" -Subject "New Application Request has been submitted" -Body $body
#Append the current objects GUID to GUIDList.txt
$_.RequestGuid | Out-File $GUIDFilePath -Append
}
}
#Remove the GUIDList.txt file and re-create it when there's more than 100 entries
$GUIDCount = $GetGUID.Count
if ($GUIDCount -gt 100) {
Get-Item $GUIDFilePath | Remove-Item
New-Item -Path $FilePath -Name GUIDList.txt -ItemType file
}

Implement the script in your environment

In order to implement the script in your environment, you’d need to change a couple of parts in the script. Remember to remove the <> characters when you edit the script. Change the following variables value:
$SiteCode = “<your_Primary_Site_site_code>
$ComputerName = “<NetBIOSName>
$GUIDFilePath = “<path_to_a_text_file_called_eg_GUIDList.txt>
$FilePath = “<path_to_the_parent_folder_of_your_GUIDList.txt_file>
The row below also needs to be modified in order for it to be able to send emails correctly:
Send-MailMessage -SmtpServer “<smtp_server_FQDN>” -From “[email protected]” -To “[email protected]” -Subject “New Application Request has been submitted” -Body $body

Nickolaj Andersen

Chief Technical Architect and Enterprise Mobility MVP since 2016. Nickolaj has been in the IT industry for the past 10 years specializing in Enterprise Mobility and Security, Windows devices and deployments including automation. Awarded as PowerShell Hero in 2015 by the community for his script and tools contributions. Creator of ConfigMgr Prerequisites Tool, ConfigMgr OSD FrontEnd, ConfigMgr WebService to name a few. Frequent speaker at conferences such as Microsoft Ignite, NIC Conference and IT/Dev Connections including nordic user groups.

27 comments

  • Before I test this I cannot determine if the GUIDList.txt file is something that must be created manually before you run this or something that gets generated by running the script. It appears that you need to manually create the text file but with what type of entries?

    • @Gary: The guidlist is generated by the script when it finds an app. request

  • The script/comment I just added.
    Can I ask you to remove the IP to the smtp server – just as a principle 🙂
    Rgs
    Kenneth

    • Hi Kenneth,
      I’ve been using the modifyed version of Nickolaj’s script posted by Remi and I get all email notifications evenusers re-request an application after they cancel or if I cancel in the console. I will double check this again and post.

  • This script worked fine for me (SCCM CB and windows 2016 server).
    One thing: If a request is cancelled by the user, and then requested again, it will be seen as a duplicate request, and therefore not processed.
    I edited the script to handle this, by removing all requests that have denied, cancelled or installed status(2, 3 or 4 in CurrentState).
    The script is here:
    #Hard-coded variables
    $SiteCode = “site”
    $ComputerName = “computername”
    $GUIDFilePath = “somepath\somefile”
    $FilePath = “somepath”
    #Get the entries from GUIDList.txt, and cast to array type.
    $GetGUID = Get-Content -Path $GUIDFilePath
    $GetGUID = [System.Collections.ArrayList]$GetGUID
    #Get ALL Application Requests
    $GetAppRequest = Get-WmiObject -Class SMS_UserApplicationRequest -Namespace root/SMS/site_$SiteCode -ComputerName $ComputerName
    ForEach($Apprequest in $GetAppRequest)
    {
    if ($Apprequest.CurrentState -eq “1”) #Status is 1 = “Requested”:
    {
    if ($GetGUID -contains $Apprequest.RequestGuid)
    {
    Write-Host “Application request $($Apprequest.RequestGuid) already present”. #Do nothing
    }
    else
    {
    #If CurrentState = 1, and ID doesn’t exist in the file then send email, add to the file (array);
    $appUser = $Apprequest.User
    $appName = $Apprequest.Application
    $appComment = $Apprequest.Comments
    $Body = @”
    Application request: $appName
    User: $appUser
    Comment: $appComment
    “@ #This row can’t contain any blank spaces or tabs
    #Email configuration
    Send-MailMessage -SmtpServer “XXXXXXXX” -From “fromaddress” -To “toaddress” -Subject “Somes subject” -Body $body
    #Append the current objects GUID to GUIDList.txt
    $GetGUID.Add($Apprequest.RequestGuid)
    }
    }
    else #If status is everything BUT 1 (requested), and the ID exist in the array, then remove it for possible re-request:
    {
    if ($GetGUID -contains $Apprequest.RequestGuid)
    {
    Write-Host “Status is 2,3 eller 4, og Application request $($Apprequest.RequestGuid) exist in the file – delete the entry.”
    $GetGUID.Remove($Apprequest.RequestGuid)
    }
    }
    }
    #When done, write the array to the file:
    $GetGUID | Out-File $GUIDFilePath -Force

  • I have a problem.
    This article script can not be executed because the mail server authentication is required.
    Proposed in the comments do not nichgeo performs error bunch.

  • I made a working powershell sxcript by combining 2
    This script includes user ad properties check for email, sur and givenname..
    #####################################################################
    ### E-Mail-Notification for Application-Request in ConfigMgr 2012 R2
    ### powered by Andre Picker – http://www.clientmgmt.de
    ### https://twitter.com/clientmgmt
    #####################################################################
    ### import ad module #################################################
    Import-Module activedirectory
    ### Set GUID textfile variables #################################################
    $GUIDFilePath = “D:\_Administration\Scripts\emailnotificationsccmapprequest\GUIDList.txt”
    $FilePath = “D:\_Administration\Scripts\emailnotificationsccmapprequest”
    ### E-Mail Settings #################################################
    $SmtpServer = “smtp.ru.nl”
    $SenderMail = “[email protected]
    $TargetMail = “[email protected]
    $Subject = “Application Catalog Request”
    $Message = “You have received a new Application Request from System Center Configuration Manager:`n”
    $Footer = “To process the request go to: \Software Library\Overview\Application Management\Approval Requests.`n`n*** This is an automatically generated email. Please do not reply to this message. ***”
    ### Queryinterval ####################################################
    $interval = $(Get-Date).AddMinutes(-60)
    ### Get SMS.Sitecode #################################################
    $smsproviderloc = “select * from sms_providerlocation”
    $sitecode = Get-WmiObject -Query $smsproviderloc -Namespace “root\sms” -ComputerName localhost
    $sitecode = $sitecode.sitecode
    ### Query ############################################################
    $GetGUID = Get-Content -Path $GUIDFilePath
    Get-WmiObject -Namespace “root\SMS\Site_$sitecode” -Class SMS_UserApplicationRequest | where {$_.CurrentState -match “1” -and [Management.ManagementDateTimeConverter]::ToDateTime($_.LastModifiedDate) -gt $interval} | Foreach-Object {
    if ($GetGUID -contains $_.RequestGuid) {
    Write-Host “Application request $($_.RequestGuid) already present”
    }
    else {
    $User = $_.User
    $Userv2 = $User.Trim(“RU”)
    $Userv3 = $Userv2.Trim(“\”)
    $Application = $_.Application
    $Comments = $_.Comments
    $Date = [Management.ManagementDateTimeConverter]::ToDateTime($_.LastModifiedDate)
    $ADsearch = Get-ADuser -Identity $Userv3 -Properties * | Select-Object GivenName, Surname, EmailAddress
    $Givenname = $ADsearch.GivenName
    $Surname = $ADsearch.Surname
    $MailAddress = $ADsearch.EmailAddress
    Write-host $Userv3 $Givenname
    Send-MailMessage -From $SenderMail -Subject “$Subject from $Givenname $Surname ” -To $TargetMail -Body “$Message`nRU-Account: $userv3`nName: $Givenname $Surname`nEmail: $MailAddress`nApplication: $Application `nDate: $Date `nComments: $Comments `n`n$Footer” -SmtpServer $SmtpServer
    $_.RequestGuid | Out-File $GUIDFilePath -Append
    }
    }
    #Remove the GUIDList.txt file and re-create it when there’s more than 100 entries
    $GUIDCount = $GetGUID.Count
    if ($GUIDCount -gt 100) {
    Get-Item $GUIDFilePath | Remove-Item
    New-Item -Path $FilePath -Name GUIDList.txt -ItemType file
    }

  • Hi,
    Before creating a schedule task I wanted to make sure the script works, but it fails.
    GUIDList.txt file is located in C:\emailNotification (on site server)
    I set the variables as follows:
    $SiteCode = “ISU”
    $ComputerName = “”
    $GUIDFilePath = “C:\emailNotification\GUIDList.txt”
    $FilePath = “C:\emailNotification\”
    I also customized my email sender, smptserver, email receiver but I am having the error below when running the script manually.
    Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
    At C:\emailNotification\emailNotification.ps1:11 char:18
    + $GetAppRequest = Get-WmiObject -Class SMS_UserApplicationRequest -Namespace root …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

  • please i need to ask about the GUID file, is that file i create locally or where it is created ?

  • that’s beautiful! Elegant and simple solution, thank you so much for sharing your work!
    no issue at all implementing this, awesome!

    • Hi Martin and John,
      Sorry for not fixing this any sooner, but the post has been amended with the correct link now. And thanks to you Martin for pointing John in the right direction 🙂
      Regards,
      Nickolaj

  • The link describing how to setup the scheduled task is not working. Will you please provide this info, thanks? I assume I could just run with an SCCM Admin account but I wanted to know for sure.

  • Nickolaj, So far this is working great. One question: is there a way to define a variable in order to add the user’s full name to the email message in addition to the account name?

    • Hi Steve,
      Yes, of course there is. But then the account setup to run the task would also need to have atleast read access to AD. If you want to do this with the Active Directory cmdlets, you’d need to import that module at the top of the script. That module would also need to be ‘installed’ on the server where the script is running (I’d not recommend to run it on a domain controller).
      But instead of using the cmdlets, you could use ADSI. Here’s a sample script that I just tested:
      $User = “nickolaj”
      $ADSearch = New-Object DirectoryServices.DirectorySearcher
      $ADSearch.Filter = “(&(objectCategory=user)(samAccountName=$User))”
      $FullName = $ADSearch.FindOne().Properties.displayname
      The $FullName variable will hold the value of ‘displayname’. Bare in mind, the Properties seems to be case sensitive.
      Regards,
      Nickolaj

  • Hi,
    got some troubles with that script. I think I’m just thinking to much ^^ I copied your script and saved it in a *.vbs is that right? When I try to run that script via cscript.exe *.vbs i get a VBScript compilation error.
    Any help would be appreciated.
    Kind regards,
    Armin

    • Hi Armin,
      This script is a PowerShell script, not a VBScript. Open your favorite text editor or PowerShell ISE and copy the script into it, then save it as a PS1 file (PowerShell ISE will do that automatically).
      Regards,
      Nickolaj

  • I customized your script and set it to run via Task Scheduler but the task runs and never stops nor does it appear to be doing anything.

    • Hi Jeff,
      Interesting, I’ve set it up a few times and it works flawlessly. Could you share a bit more information of you’ve set it up? What’s the action command in the task? Are you able to run the script from a console and get the desired results?
      Regards,
      Nickolaj

  • The script works great, it emails me all requests; however, items are not appending to the txt file, therefor I am getting duplicate emails each time it runs.

    • Hi Jrmendi,
      If you try this script, a modified version to only test the basic functionality:
      $SiteCode = “P01”
      $ComputerName = “

  • Nice script, however it doesn’t show which attributes should be changed to work in the users own environment, you state that they should be in red but there not! would also be handy to explain what each attribute to be changed does/is there for.

    • Hi Pieman,
      You’re totally right, I forgot to remove that part when I migrated all posts from the previous blog. The blog post has now been updated with the corrections that you asked for. Let me know if you still think it’s unclear.
      /Nickolaj

      • excellent, works a dream, and negates the need to implement another application (MS SCSM or Cortech’s CTAA).
        Many thanks and keep up the good work!

      • Great and thanks! I’m glad that you got it working. If you are looking into some self service portal, have a look at http://www.eupsco.com.I recently implemented it in production and its really great. The best thing is that its free and customizable.
        /Nickolaj

Sponsors