Search code examples
powershelloffice365jobs

Using New-MailContact, Set-MailContact, and Set-Contact inside background jobs


Here's the updated, still getting the same errors.

$UserCredential = Get-Credential
$contacts = Import-Csv "C:\temp\testgal.csv"
    Start-Job -Name Loop -ScriptBlock {
        param([pscustomobject[]]$contacts, [System.Management.Automation.PSCredential[]]$UserCredential)
        $session2 = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
        Import-PSSession $session2
        Connect-MsolService -cred $UserCredential
        foreach ($c in $contacts){
        ........
        }
    } -ArgumentList (,$contacts, $UserCredential)
Wait-Job -State Running | Receive-Job
Get-Job -State Completed | Remove-Job

I'm trying to create a vast number of contacts in 365 using a script and would like to run parallel jobs to speed it up, I built a loop inside a job and tested it worked using the following inside the loop to make sure it could extract the correct variables from the CSV.

$name = $c1.displayname
New-Item -Path "C:\Temp\Output" -Name "$name"  -ItemType "file"

Now when I attempt to run the loop with the commands in the title as below

 $contacts = Import-Csv "C:\temp\gal\testgal.csv"
       Start-Job -Name Loop -ScriptBlock {
           param([pscustomobject[]]$contacts)
            foreach ($c in $contacts){
                $name = $c.displayName
                $rawProxy = $c.proxyAddresses
                $proxysplit = $rawproxy -split '(?<!\\);'
                $proxyquoted = $proxysplit.replace('x500','"x500').replace('x400','"x400').replace('X500','"X500').replace('X400','"X400')
                $proxy = $proxyquoted
                New-MailContact -ExternalEmailAddress $c.Mail -Name "`"$name`"" -Alias $c.mailNickname -DisplayName $name -FirstName $c.givenName -Initials $c.initials -LastName $c.sn -AsJob
                Set-MailContact -Identity $c.mailNickname -CustomAttribute1 "CreatedWithScript" -CustomAttribute3 $c.extensionAttribute3 -EmailAddresses $proxy -AsJob
                Set-Contact -Identity $c.mailNickname -City $c.l -Company $c.company -Department $c.department -Office $c.physicalDeliveryOfficeName `
                    -Phone $c.telephoneNumber -PostalCode $c.postalCode -Title $c.title -AsJob
           }
       } -ArgumentList (,$contacts)
       Wait-Job -State Completed | Receive-Job
       Get-Job -State Completed | Remove-Job

It fails saying the following for each loop:

The term 'New-MailContact' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. + CategoryInfo : ObjectNotFound: (New-MailContact:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException + PSComputerName : localhost

The term 'Set-MailContact' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. + CategoryInfo : ObjectNotFound: (Set-MailContact:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException + PSComputerName : localhost

The term 'Set-Contact' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. + CategoryInfo : ObjectNotFound: (Set-Contact:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException + PSComputerName : localhost

Is there a trick to running these commands inside background jobs?


Solution

  • You need to import the correct powershell module, in this case the Office365:

    Import-Module MSOnline
    

    You will also need to authenticate so pass username and password down to your job and create credentials objects:

     $contacts = Import-Csv "C:\temp\gal\testgal.csv"
           Start-Job -Name Loop -ScriptBlock {
               param([pscustomobject[]]$contacts, [string]$username, [string]$password)
                Import-Module MSOnline
                $secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
                $creds = New-Object System.Management.Automation.PSCredential ($username, $secpasswd)
                $O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $creds -Authentication Basic -AllowRedirection
                Connect-MsolService –Credential $creds
                foreach ($c in $contacts){
                  ...
               }
           } -ArgumentList (,$contacts, $username, $password)
           Wait-Job -State Completed | Receive-Job
           Get-Job -State Completed | Remove-Job
    

    NB. This is untested but should put you on the right track.