Posts Tagged ‘one-liner’

One Liner – See Number Of Connected Users, Endpoints On A Lync Front End Server

January 22, 2015 2 comments

A question went around an internal DL at work today asking if anyone knew off the top of their head the name of performance counters that show connected users and endpoints. While digging up the answer, I started thinking – this would be a great little one liner.

My esteemed colleague Ron Cook (@roncook925) beat me to supplying the answer to the DL question. The two counters are:

LS:USrv – Endpoint Cache\USrv – Active Registered Endpoints
LS:USrv – Endpoint Cache\USrv – Active Registered Users

Endpoints is always higher than users, in my experience. There are always some users who are connected via mobile devices and rich client, or via OWA, or LPE. So I like to query both.

PowerShell has a great cmdlet called Get-Counter which, as you can guess, can query performance counters. There’s a pretty good tutorial on how to retrieve perfmon counter data for Lync related counters by the Lync PowerShell group at Microsoft in How Do We Love Performance Counters” Let Us Count the Ways. So let’s take a look at how we can get the data we need.

In this case, we’ll query the two counters mentioned above with one line. This is supported in Get-Counter by just separating the counters with a comma. We’ll select an expanded property called CounterSamples, which holds the data we need (among other info). And lastly, we’ll output the path (counter name), and something called the CookedValue, which is the actual counter value contained within CounterSamples. I know, CookedValue sounds like it could be just made up numbers, like those you get from a shifty accountant. But it is truly the value we want.

Plug this into your console as one long line:

Get-Counter "\LS:USrv - Endpoint Cache\USrv - Active Registered Endpoints","\LS:USrv - Endpoint Cache\USrv - Active Registered Users" | Select-Object -ExpandProperty CounterSamples | Format-Table Path,CookedValue -Auto

That will give you a quick point-in-time snapshot of the number of users and endpoints connected to the front end, as shown below.


The blurred text is just the front end name. If you’d like to query a remote front end, just tack on the ComputerName parameter, such as:

Get-Counter "\LS:USrv - Endpoint Cache\USrv - Active Registered Endpoints","\LS:USrv - Endpoint Cache\USrv - Active Registered Users" -ComputerName | Select-Object -ExpandProperty CounterSamples | Format-Table Path,CookedValue -Auto

For those wondering why I’m using Format-Table and the -Auto parameter, it’s because the counter path value is so long that it would otherwise get truncated short enough to where you wouldn’t know which counter was tied to which value.

One Liners: Finding Elevated Accounts That Are Enabled For Lync

November 18, 2014 3 comments

Lync 2013 logo 128x128One thing I see while doing Lync environmental health checks for some customers is some elevated accounts that are enabled for Lync. An example is members of the Domain Admins group. This can be somewhat problematic, especially for administration of those elevated accounts. For security reasons, it is not recommended to enable members of Domain Administrators group for Lync.

You cannot use Lync Server Control Panel to manage users who are members of the Domain Admins Active Directory group. For Domain Admins users, you can use Lync Server Control Panel only to perform read-only search operations. Attempting to perform write operations (such as enable or disable for Lync Server Control Panel, change pool or assigned policies, telephony settings, SIP address) on an elevated user will yield an “Access Denied” error. To perform write operations on a member of Domain Admins, you must use Lync Server Management Shell (PowerShell) cmdlets while logged on as a member of Domain Admins.

For more information please refer to this Microsoft page: User accounts enabled for Lync Server 2013

To query an elevated group, such as Domain Admins, for Lync enabled users, use the following:

(Get-ADGroupMember "Domain Admins").DistinguishedName | Get-CsUser -ErrorAction SilentlyContinue | Format-Table DisplayName,SipAddress

You can replace the “Domain Admins” with the name of any group, really. When you run it, you’ll end up with something like:

PS C:\> (Get-ADGroupMember "Domain Admins").DistinguishedName | Get-CsUser -ErrorAction SilentlyContinue | Format-Table DisplayName,SipAddress

DisplayName                                                 SipAddress
-----------                                                 ----------
Dan Giles                                         
Neil Armstrong                                    
Dawn Lopes                                        
Bob Seger                                         
Gail O'Grady                                      
Troy Dallas                                       
Steve Carrell                                     

You can Lync disable these users for Lync, using the Disable-CsUser cmdlet. This can be done either individually using the -Identity parameter, or everyone at once by pipeline, with something like:

(Get-ADGroupMember "Domain Admins").DistinguishedName | Disable-CsUser -ErrorAction SilentlyContinue

If you have some accounts that were previously members of an elevated group like Domain Admins, but no longer are, then the AdminCount parameter on their account may still be set. This will cause the Access Denied issue to continue. You can manually change this on the user object using ADSIEDIT, or via a script such as Set-AdminUser.

One Liner: See Who You’re Openly Federating With

August 12, 2013 1 comment

Wanna see who you’re dynamically (openly) federating with in Lync Server? It’s pretty straightforward with the Get-EventLog cmdlet. All we need to do is look for the most recent entry in the Lync Server event log with event ID 14601. One an Edge server, open PowerShell and run the following:

Get-EventLog "Lync Server" | Where-Object {$_.EventId -eq 14601} | Select-Object EventId, Message -First 1 | Format-List *

The description of the single returned event will list the domains you’re currently dynamically federating with. You’ll get something back like this:

EventID : 14601
Message : Report of discovered partners that the Access Edge Server is
          currently monitoring.
There are 21 discovered partners, identified by the common name of
their certificate.
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:
Name:; Domains:*

A note that as the Message field of the event log entry mentions, these are DISCOVERED PARTNERS – those found through SRV records. If you want to see who you’re federating with using enhanced or direct federation (those specifically defined in your Lync environment), from a non-Edge Lync server, run Get-CsAllowedDomain. For a breakdown on the various types of federation, see Kevin Peter’s excellent post A Few Words on Federation.

Categories: Lync Server Tags: ,

One liners: Get All Exchange Users Who Are Configured for Forwarding

May 7, 2013 3 comments

Exchange 2013 logo 128x128Due to some legal requirements, I had a needed to list all users who were configured in Exchange to forward elsewhere. This was to ensure that mail wasn’t automatically leaving the environment. A simple, single line in the shell is all that’s needed to give me what I need.

Open Exchange Management Shell, and enter this:

Get-Mailbox -Resultsize Unlimited | ? {$_.ForwardingAddress}

We can clean this up and make it a little more presentable using something like:

Get-Mailbox -Resultsize Unlimited | Where-Object {$_.ForwardingAddress} | Select-Object Name, @{Expression={$_.ForwardingAddress};Label="Forwarded to"}, @{Expression={$_.DeliverToMailboxAndForward};Label="Mailbox & Forward"}

And the results are a small table that shows the user name, which object mail is being forwarded to, and whether the mailbox is configured to both store and forward:


This allowed me to take a look at those user accounts, and disable the forwarding, forcing the users to use their Exchange mailbox.

For a long list, or if you just want the info in a file, we can export the results to a .csv using Export-Csv. To do this, use:

Get-Mailbox -Resultsize Unlimited | Where-Object {$_.ForwardingAddress -ne $null} | Select-Object Name, @{Expression={$_.ForwardingAddress};Label="Forwarded to"}, @{Expression={$_.DeliverToMailboxAndForward};Label="Mailbox & Forward"} | Export-Csv c:\forwardedusers.csv -NoTypeInformation

One liners: List All Users Who Have Send-As Access To Other Mailboxes

October 23, 2012 1 comment

Exchange 2013 logo 128x128If you need to list all users who have Send-As access to other user’s mailboxes in Exchange, try this little one-liner from Exchange Management Shell:

Get-Mailbox -ResultSize unlimited | Get-ADPermission | Where {$_.ExtendedRights -like "Send-As" -and $_.User -notlike "NT AUTHORITY\SELF" -and (! $_.Deny)} | fl Identity,User,AccessRights,IsInherited

This will show you the user who has the right and the mailbox they have rights to.

Send-As rights

Send-As rights. Click to enlarge.

Note that I use fl (Full List) instead of ft (Full Table) because the identity field can be quite long.

One Liners: Setting Recovery Option to ‘restart’ for Lync Services

October 5, 2011 2 comments

Lync 2013 logo 128x128A client wanted to configure the recovery options for services in Lync to help reduce downtime if/when a service stops. This was no big deal for me, except there are a dozen Lync servers, some of which have quite a few Lync services. I set out to make this easier than manually changing each service’s recovery options.

Service recovery options allow you to define what Windows should do if the service fails. The options are “Take No Action” (the default), “Restart the Service”, “Run a Program”, and “Restart the Computer”. These options can be defined for the first, second, and subsequent service failures. Additional parameters include how long to wait before resetting the failure counter and how long to wait after the service fails before performing the configured failure option. More complex options include running another program:

Default service recovery options before running sc.exe

Default service recovery options before running sc.exe

Unfortunately, PowerShell’s Set-Service doesn’t have a parameter for setting failure options, so we must rely on the command line sc.exe. Sc.exe can be used to create, modify, and delete services. We’ll use this to set our failure options to restart the services. Note: you must use “sc.exe” and not just “sc”, since in PowerShell, “sc” is an alias for Set-Content. The format is

sc.exe [service name] failure reset= [integer] actions= [actions]

Reset is measured in seconds. We’ll use 86400, which is a full 24 hours. Actions are specified as action/wait time in milliseconds. So “restart/5000″ means to wait 5000 milliseconds (5 seconds), and then restart the service. The same action will be applied to the first, second, and subsequent service failure.

We’ll use Get-WMIObject win32_service to grab a list of all of the services, piping that to match descriptions that include “Lync”, and start modes that are “automatic”. The finished one liner command looks like this:

$services = Get-WMIObject win32_service | Where-Object {$_.description -imatch "Lync" -and $_.startmode -eq "Auto"}; foreach ($service in $services){sc.exe failure $ reset= 86400 actions= restart/5000}
Recovery options changed

Recovery options changed (click to enlarge)

When we view the properties of the service again, we see that the failure options are set to restart the service, and to reset the counter after 1 day. Since the restart option is only 5 seconds, the “Restart service after” field shows 0 minutes:

Service recovery options after running sc.exe

Service recovery options after running sc.exe

You can also specify different actions for each of the failure instances by adding more actions. For instance, let’s say you want to restart the service for the first and second failures, and reboot the server on subsequent failures. Simply combine the actions together, separating them with a slash, such as:

$services = Get-WMIObject win32_service | Where-Object {$_.description -imatch "Lync" -and $_.startmode -eq "Auto"}; foreach ($service in $services){sc.exe failure $ reset= 86400 actions= restart/5000/restart/5000/reboot/5000}

Obviously, a good monitoring solution such as System Center Operations Manager (SCOM) should be used to track and alert when services stop, and when other more serious issues arise. You don’t want to get into a scenario where a service is constantly stopping and being restarted without knowing.

One Liners: Finding Out Which Lync Pool Servers a User is Associated With, and the Preferred Connection Order

August 31, 2011 3 comments

Lync 2013 logo 128x128Sometimes, you need to do some Lync logging to investigate a problem with a user. If you have multiple servers in a pool, you sometimes have to enable logging on each until you figure out which one the client is actually connecting to. We can find out which servers the user is associated with and the preferred order that the client will connect using the following in the Lync Management Shell:


Such as:


The output shows us the primary and backup pool FQDNs, and the order in which it will connect to servers in each pool.

PrimaryPoolFqdn                     : lyncpool01.contoso.local
BackupPoolFqdn                      : lyncpool02.contoso.local
UserServicesPoolFqdn                : lyncpool01.contoso.local
PrimaryPoolMachinesInPreferredOrder : {1:2-2, 1:2-1}
BackupPoolMachinesInPreferredOrder  : {1:3-2, 1:3-1}

But what that doesn’t tell us, is the actual names of the servers in the pool, and which one is 1:2-2, and 1:2-1, etc. So we expand a little further and use:

Get-CsUserPoolInfo –Identity "user" | Select-Object –ExpandProperty PrimaryPoolMachinesInPreferredOrder

For example,

Get-CsUserPoolInfo –Identity "prichard" | Select-Object –ExpandProperty PrimaryPoolMachinesInPreferredOrder

This will show the registrar pools and their respective servers in the preferred order the user will connect:

MachineId         : 1:2-2
Cluster           : 1:2
Fqdn              : lyncpoolserver03.contoso.local
PrimaryMacAddress : 000000
Topology          : Microsoft.Rtc.Management.Deploy.Internal.DefaultTopology
MachineId         : 1:2-1
Cluster           : 1:2
Fqdn              : lyncpoolserver02.contoso.local
PrimaryMacAddress : 000000
Topology          : Microsoft.Rtc.Management.Deploy.Internal.DefaultTopology

We see that this user will connect to lyncpoolserver03 first, since it’s listed first. If that server is not available, then the user would be redirected to lyncpoolserver02. Note that this only shows the information for the primary pool. If you have a backup pool, the information for those servers is not shown here (but is shown if you use BackupPoolMachinesInPrefferedOrder as the ExpandedPropery). However, if you do have a backup registrar pool, and want to use it as a backup  pool for users homed on the first, you should have Director servers, as mentioned in Another Reason to Include a Director in Your Lync Server 2010 Deployment.

We can then wrap this in a function:

function Get-CsUserConnectionInfo {
 param (
  [parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, HelpMessage="No username specified")]
 Get-CsUserPoolInfo –Identity $user | Select-Object –ExpandProperty PrimaryPoolMachinesInPreferredOrder
} # end function Get-CsUserConnectionInfo

For easy access. Toss it into your PowerShell profile and acces it using


Also, the Get-CsConnections.ps1 script will show you the current connections on a per-user basis if needed.

One Liners: See Failed Inbound Messages for the Past Few Days

August 22, 2011 Leave a comment

Exchange 2013 logo 128x128Dealing with spam is like herding cats. It moves in every direction, and just when you think you might have it corralled, something comes along in a completely different direction.

Exchange has some fabulous features for reducing the amount of spam that lands in end-user mailboxes, and those features are well documented. Sometimes, you just want to see what’s being stopped. That’s where today’s one liner comes in. This little tidbit will troll through the tracking logs of the server you run it on, and display the failed messages from the last 7 days – most of which are stopped by the Content Filtering Agent. Of course, you can change the number of days to look back, as larger environments will no doubt have a tremendous number of failed messages. Here we see the sender’s email address, recipients, message subject, and the time stamp when the message was attempted.

Get-MessageTrackingLog -ResultSize unlimited -Start ((Get-Date).AddDays(-7)) | Where-Object {$_.EventId -eq "fail"} | Select-Object Sender,Recipients,MessageSubject,TimeStamp

We can specify a specific server to search on:

Get-MessageTrackingLog -ResultSize unlimited -Server  -Start ((Get-Date).AddDays(-7)) | Where-Object {$_.EventId -eq "fail"} | Select-Object Sender,Recipients,MessageSubject,TimeStamp

Or, search all servers:

Get-TransportServer | Get-MessageTrackingLog -ResultSize unlimited -Start ((Get-Date).AddDays(-7)) | Where-Object {$_.EventId -eq "fail"} | Select-Object Sender,Recipients,MessageSubject,TimeStamp

And, we can also dump the data to a .csv file for manipulation:

Get-MessageTrackingLog -ResultSize unlimited -Start ((Get-Date).AddDays(-7)) | Where-Object {$_.EventId -eq "fail"} | Select-Object Sender,Recipients,MessageSubject,TimeStamp | Export-Csv c:\failedmessages.csv


one liners: Restarting Stopped Services

August 18, 2011 3 comments

PowerShell-logo-128x84During a recent power “issue”, I had to restart an entire rack full of Hyper-V servers. While an Exchange VM was booting, a networking issue caused the VM to not be able to connect to anything else, including domain controllers. As a result, many services couldn’t start. Rather than bouncing the server, or manually starting the services, this little one liner came in handy. Unfortunately, Get-Service doesn’t expose the startmode. That would make it too easy. So, we use Get-WMIObject:

Get-WMIObject win32_service | ? {$ -match "exchange" -and $_.startmode -eq "Auto" -and $_.state -ne "running"} | Start-Service

Of course, we can remove the name check and look for all services on the server that should be (but aren’t) started, and start them:

Get-WMIObject win32_service | ? {$_.startmode -eq "Auto" -and $_.state -ne "running"} | Start-Service

Ståle Hansen has reminded me that in Lync, there is also another solution:

Get-CsWindowsService -ExcludeActivityLevel | ? {$_.Status -like "Stopped"} | Start-CsWindowsService

one liners: Finding users with forwarding addresses set

August 16, 2011 2 comments

Exchange 2013 logo 128x128Sometimes while implementing new corporate policies, such as those that control forwarding messages outside of an environment, an admin needs to figure out who is configured that way. This can be a daunting task to go down through every account, visually inspecting each. PowerShell comes to the rescue in this one liner:

Get-Mailbox -Resultsize Unlimited | Where {$_.ForwardingAddress -ne $null} | Select Name, @{Expression={$_.ForwardingAddress};Label="Forwarded to"}, @{Expression={$_.DeliverToMailboxAndForward};Label="Mailbox & Forward"}

As we see in our test, one user, Robert Sweet, is configured for forwarding. His account forwards to a contact called “Robert Sweet [External]”, and based on the Mailox & Forward being False, we know that it only forwards to the external address, and does not also deliver to the Exchange mailbox.

If we needed to, we could use

Get-Contact "Robert Sweet [External]" | fl

to get info about the contact, including the destination SMTP address. If we need to disable forwarding for all of the enabled users, we can use

Get-Mailbox -Resultsize Unlimited | Where {$_.ForwardingAddress -ne $null} | Set-Mailbox -ForwardingAddress $null