Tuesday, July 22, 2014

Exchange 2010 - Set-MailContact

Today I received a request to upgrade over a 100 contacts to a new external email address as the companies email had change. So for course I would not ever do it manully, and I wrote a script for it. 

$ConfirmPreference = "None"
$contacts = Import-csv 'H:\FILENAME.csv'

Foreach($contact in $contacts)
{
    if($contact.CurrectExternalAddress.Length -gt 0)
    {
        Set-MailContact -Identity $contact.CurrectExternalAddress -ExternalEmailAddress $contact.NewExternalAddress -Confirm:$false -ForceUpgrade
    }


But I just could not get it working automatically, it kept prompting to me to upgrade each contact to 2010. Which is fine, but it was making me press Enter for each change. I looked over it and I tried to do "ConfirmPreference" and "-Confirm:$true/$false" without much success. It wasn't until I read somewhere to try "-Force" that I found the "-ForceUpgrade" which allowed the upgrade to happen without a prompt. 

I honestly had never seen that parameter before. Maybe this will be useful to one of you, and might save you some time. 

Monday, July 21, 2014

Terminal Server has exceeded max number of connections

I received a call requesting assistance one of our users is unable to remote into an SQL server. He is receiving the following error:

kb-terminal-max-connections

I tried to remote as well but received the same error. Then I started researching on how to find the users that are logged in, so that he may communicate with them and ask them to log off, but this brought a very limited amount of information. I found out that the class Win32_LoggedOnUsers doesn't really give you that information, but then I found out that there is a way to bypass the maximum number of connections by using the following command:

%systemroot%\system32\mstsc.exe /admin
Once I logged in I was able to go through the Task Manager and find and log off the extra user, but I was not happy with this solution. I feel like it might not always work. After further looking into this issue I found in Learn-PowerShell that I was able to use the WMI Class Win32_Process to get the Explorer.exe process and get the Owner, thus revealing the logged on users. 

Script found in sauce:
Function Get-WMIComputerSessions {
<#
.SYNOPSIS
    Retrieves tall user sessions from local or remote server/s
.DESCRIPTION
    Retrieves tall user sessions from local or remote server/s
.PARAMETER computer
    Name of computer/s to run session query against.
.NOTES
    Name: Get-WmiComputerSessions
    Author: Boe Prox
    DateCreated: 01Nov2010
.LINK
.EXAMPLE
Get-WmiComputerSessions -computer "server1"
Description
-----------
This command will query all current user sessions on 'server1'.
#>
[cmdletbinding(
    DefaultParameterSetName = 'session',
    ConfirmImpact = 'low'
)]
    Param(
        [Parameter(
            Mandatory = $True,
            Position = 0,
            ValueFromPipeline = $True)]
            [string[]]$computer
    )
Begin {
    #Create empty report
    $report = @()
    }
Process {
    #Iterate through collection of computers
    ForEach ($c in $computer) {
        #Get explorer.exe processes
        $proc = gwmi win32_process -computer $c -Filter "Name = 'explorer.exe'"
        #Go through collection of processes
        ForEach ($p in $proc) {
            $temp = "" | Select Computer, Domain, User
            $temp.computer = $c
            $temp.user = ($p.GetOwner()).User
            $temp.domain = ($p.GetOwner()).Domain
            $report += $temp
          }
        }
    }
End {
    $report
    }
}

But I didn't quite need all this so I simply made a one line :

(gwmi win32_process -computer SERVERNAME -Filter "Name = 'explorer.exe'").GetOwner().User 

Now I am able to find out the users that are logged in without having to remote into the server. 

Hope this might help other people out there!