Monday, January 14, 2013

Creating a Conferencing Directory after you delete it

In OCS 2007 R2, the decommission steps are widely documented by both Microsoft Technet and many other bloggers.  And with Lync 2010 and Lync 2013 now being generally available, I find myself cleaning up a few OCS 2007 R2 implementations.  I got fairly comfortable with the steps, and I goofed on the order of things.  I removed the assigned conferencing directories to an OCS pool before I deactivated the Conferencing Attendant.

I found this related post on Lee Desmond's blog, which matched the error I was receiving in my attempted deactivation:

"A call to a subtask failed.: The call to subtask AppServer.GetAppState failed. Pool is not ready."

The error associated was  0xc3FC200D

I searched a while and finally found that I made the mistake of removing the conferencing directory prior to deactivating the Conferencing Attendant.  Simple, enough - I'd just need to create a new conferencing directory.  Only there is not a way to do so in the OCS GUI.  So I had to take to ADSIEdit.msc for this one.

Much of this is thanks to this blog entry, which solves a different issue, but contained most of the knowledge I needed!

Open ADSIEDIT.
Navigate to the following:
CN=Configuration.
CN=Configuration,DC=,DC=com
CN=Services.
CN=RTC Service.
CN=Conference Directories.

Right Click on "CN=Conference Directories".
New -> Object
On the New Windows that opens which says "Select a Class:" choose msRTCSIP-ConferenceDirectory
In the Value Field type 2.
Note:- Value Field corresponds to the Common-Name of the Conference Object that we are creating.

Click on Next.
Click on Finish.

Now under the "CN=Conference Directories" we will see the new Directory Created with name "CN=2".

Now expand the following.
CN=Configuration.
CN=Configuration,DC=,DC=com
CN=Services.
CN=RTC Service.
CN=Pools
CN=
CN=Microsoft
CN=LC Services

Right Click on "CN=LC Services" and go to properties.
Check for the Attribute called distinguishedName.
Copy the value of distinguishedName.

Now expand the following.
CN=Configuration.
CN=Configuration,DC=,DC=com
CN=Services.
CN=RTC Service.
CN=Conference Directories.
Cn=2

Right Click on the "CN=2" and go to the Properties.
Check for the Attribute msRTCSIP-ConferenceDirectory.
Paste the distinguishedName Value here.

Also check for the Attribute msRTCSIP-ConferenceDirectoryId
Enter the Value 2 there.
Now, close and reopen (refresh didn't seem to pull the update) your OCS server console, and you should see your Conferencing Directory ID of "2" show up again.  Now you can deactivate the Conferencing Attendant successfully!

Tuesday, December 11, 2012

Lync Profiles tool for Lync 2010 and 2013

OK, So I typically only post things here when I learn them or document them myself...   but today I am posting something just for the sheer amount of time it will save me, and possibly you.  I reached out to co-worker and well known Lync blogger Jeff Schertz asking if he has ever heard of a way to have profiles in Lync like you can in Outlook.  I spend about 20-30 minutes per day retyping SIP URI's, server names, etc to sign into multiple Lync environments.  To my amazement, he replied  minutes later with this gem.

Lync Profiles for Lync 2010
Lync Profiles for Lync 2013

This really simple tool allows you to have preconfigured Lync profiles and allows for a single click to sign out of one environment/user and into another.  Most excellent!  Thanks Jeff!


Thursday, September 06, 2012

Move Mailboxes and Notify Users

I wrote this script for an Exchange 2003 to Exchange 2010 migration. The administrator wanted a way to communicate with users when their mailbox move was complete, as well as give him a way to monitor the progress of mailbox moves without sitting in front of the computer all night.

This script was tested in an Exchange 2010 SP2 environment where anonymous relay from specific hosts was allowed. 

Purpose

The script accomplishes the following:
-        Create move requests for users specified in the $MailboxestoMove variable at the top
-        Moves each mailbox and monitors status every 30 seconds
-        Will output “Moving Users…” to the screen  every 30 seconds while moves are in process
-        As a move completes with a “complete” status, an email is sent to the user – subject and body defined by variables at the top ($MessageSubject and $MessageBody). Then, the completed move request is cleared
-        As a move request completes with a “CompletedWithWarning” status, an email is sent to the user – the subject and body are defined by variables at the top ($MessageSubject and $MessageBody). Next, an email is sent to the administrator – the subject and body are defined by variables at the top($MessageSubjectWarning and $MessageBodyWarning) – which includes the move history report so you can investigate the warning. Then, the completed move request is cleared
-        If a move request completes with a “Failed” status, then an email is sent to the administrator – the subject and body are defined by variables at the top ($MessageSubjectFailure and $MessageBodyFailure) – which includes the move history report so you can investigate the warning. Then, the failed move request is cleared.   NOTE: an email is NOT sent to the user
-      When all move requests have completed and cleared, an email is sent to the administrator – the subject and body are defined by variables at the top($MessagesSubjectComplete and $MessageBodyComplete). Once this email has been sent, the script ends.

Usability

To use the script, editing the values of the following variables is required:
-        $MailboxestoMove
-        $TargetDB
-        $SMTPServer
-        $SMTPFrom
Optionally, edit the message subject and body variables.

To run the script:
-        Open an elevated Exchange PowerShell window
-        Save the text file as a .PS1 file type rather than TXT
-        Navigate to the place the script is saved
-        Type .\MoveUsersandNotifyv2.7-Final.PS1
-        Script will begin running.

Feature Requests for a Future Version

There are a few things that I think could be improved in order to make this a really great tool.
  • Turn the script into a CMDlet. Doing that would involve wrapping the script in a function, parameterizing the 12 input variables, saving the script as a PSM1, and putting it in the /modules subfolder of your Exchange installation. If anyone does this before I get around to it, please post the updated script.
  • The script does not handle move requests that are suspended or automatically suspended. It completely ignores them. Additional code would need to be written to add script blocks to handle these two move request status types
  • The script assumes that there are no existing move requests when it begins running. If you run the script while there are existing requests, the script will get stuck in an infinite loop because it doesn't know of the existing request.

The Script

#Copyright 2012
#Author: Robin Lehr
#Last Modified Date 09/06/12
#Names of the users you would like to move, enclosed in double quotes and 

#separated by commas. Type these in the format of the user's email address

$MailboxestoMove="test@contoso.com", "test2@contoso.com"

#Type the name of the database you would like to move the users to
$TargetDB = "TestDB2"

#Set variables for sending email
$SMTPServer="smtp.contoso.com"
$SMTPFrom="administrator@contoso.com"
$MessageSubject="Your Mailbox Move is Complete!"
$MessageSubjectFailure="FAILURE: There are one or more failed move requests"
$MessageSubjectWarning="WARNING: There are one or more move requests that completed with warnings"
$MessageSubjectComplete="All Move Requests Have Been Processed" 
$MessageBody="$User - Thank you for your patience, your mailbox move request is complete"
$MessageBodyFailure="The Move request for $User has failed. The Move Request Report says: $StatusReport"
$MessageBodyWarning="The Move request for $User has completed with warnings. The Move Request Report says: $StatusReport"
$MessageBodyComplete="All Move Requests with status other than suspended are complete." 
#End of Variables

$UserstoMove=New-Object System.Collections.ArrayList
ForEach($Mailbox in $MailboxestoMove)
{
    $UserstoMove.Add($Mailbox)
}

#Create Array to remove users from loop processing
$removeUsers=New-Object System.Collections.ArrayList
ForEach ($User in $UserstoMove)
 {
     New-MoveRequest -Identity $User -TargetDatabase $TargetDB -WarningAction "SilentlyContinue"
 }
$Moves=Get-MoveRequest | Where {$_.Status -ne "AutoSuspended" -and $_.Status -ne "Suspended"}
$requests=($Moves|group-object status).count
Do 
 {
 Start-Sleep -seconds 30
 ForEach ($User in $UserstoMove) 
   {
    #Define Variable that will determine the move request status
    $MoveStatus=Get-MoveRequest -Identity $User
    if($MoveStatus.Status -eq "Completed") 
   {
          $SMTPTo=$User
          $SMTP=New-Object Net.Mail.SmtpClient($SMTPServer)
          $smtp.Send($SmtpFrom,$SmtpTo,$messageSubject,$MessageBody)
          Remove-MoveRequest $user -Confirm:$false
          $RemoveUsers.Add($User)
   }
        ElseIf($MoveStatus.Status -eq "Failed") 
   {
       #This Command will send a report for failed move requests
        $StatusReport=Get-MailboxStatistics -Identity $User -IncludeMoveReport

#In this case the email should go to the administrator, which is assumed to 
#be the same as the SMTP From Address. That is why the $SMTPFrom variable is 
#repeated twice in the send command.

        $SMTP=New-Object Net.Mail.SmtpClient($SMTPServer)
        $smtp.Send($SmtpFrom,$SmtpFrom,$messageSubjectFailure,$MessageBodyFailure)

#This script block will send the move request history report and then remove 
#the request. If you do not wish this behavior to happen, comment out the below line. 

#IMPORTANT: if the "Remove-Moverequest" line below is commented out, you 
# MUST also add the following to the Where-Object conditions of the 
# $Moves=Get-MoveRequest line above:
# -and $_.Status -ne "Failed"
            Remove-MoveRequest $User -Confirm:$false
            $RemoveUsers.Add($User)
        }

#In this case the email should go to the administrator, which is assumed to 
#be the same as the SMTP From Address. That is why the $SMTPFrom variable is 
#repeated twice in the send command.

        ElseIf($MoveStatus.Status -eq "CompletedWithWarning") 
        {
#This Command will send a report for failed move requests 
            $StatusReport=Get-MailboxStatistics -Identity $User -IncludeMoveReport
            $SMTP=New-Object Net.Mail.SmtpClient($SMTPServer)
            $smtp.Send($SmtpFrom,$SmtpFrom,$messageSubjectWarning,$MessageBodyWarning)
            $smtp.Send($SmtpFrom,$SmtpTo,$messageSubject,$MessageBody)
            Remove-MoveRequest $User -Confirm:$false
            $RemoveUsers.Add($User)
        } Else {
        Write-Host "Moving Users..."
        }
    } 


#Remove Users who are complete
    ForEach ($value in $UserstoRemove)
    {
        $UserstoMove.Remove($value)
    }

#Find the number of move requests
    $Moves=Get-MoveRequest | Where {$_.Status -ne "AutoSuspended" -and $_.Status -ne "Suspended"}
    $requests=($Moves|group-object status).count
    } 
    Until($requests -eq 0 -or $requests -eq $null) 
#Send Email to Administrator that moves are complete
$SMTP=New-Object Net.Mail.SmtpClient($SMTPServer)
$smtp.Send($SmtpFrom,$SmtpFrom,$messageSubjectComplete,$MessageBodyComplete)
 

Labels:

Wednesday, August 29, 2012

Lync 2013 - Using ClsController.exe instead of ocslogger.exe


Required Reading: 

One of the things that I felt that Jens did not cover was additional detail on sub components of the scenarios that Microsoft gives us with the new clscontroller.exe.  Below are a list of the scenarios, the text name  of the scenario, and the logging subcomponents included in the scenario.

All of this detail is attainable using the method Jens described in the bottom of his post, I just cleaned it up and made a table, so all the credit is to his work.  :)

One of the things that I have not really seen discussed or posted about much is that when using clscontroller, one of the intended benefits is that you do not have to stop/start logging.    AlwaysOn is….  Always on.  So you can just utilize the last command in Jen's blog:

.\ClsController.exe -search -pools redmond.contoso.com -components SipStack -loglevel verbose > c:\temp\redmond_sipstack_logs.txt

You can further narrow your search using -phone, -uri, or -ip like this:
.\ClsController.exe -search -pools redmond.contoso.com -components SipStack -loglevel verbose -uri john@contoso.com > c:\temp\redmond_sipstack_logs_filtered.txt

I have not been able to successfully utilize  the filters however, and started a forum post here regarding it.


Scenario
Description
Logging Subcomponents
AlwaysOn
This scenario will the one that is always running when no other scenario is active.  This is the one the registry will be configured with to enable on machine startup
AsMcu
AVMCU
AVMP
CAAServer
Collaboration
DataMCU
DataMcuRuntime
ExumRouting
IMMCU
InboundRouting
InterClusterRouting
McuInfra
MediationServer
OutboundRouting
Routing_Data_Sync_Agent
S4
ServerTransportAdaptor
Sipstack
LDM
AppShareOoty
RdpApiTrace
UserServices
UDCAgent
PNCHService
TenantAdminUI
HostedMigration
Powershell
UCWA
GCCommon
GCEndpoint
GCServer
GCCompliance
GCWebService
XmppTGW
XmppCommonLibrary
XmppListener
XmppRouting
XmppTGWProxy
Lyss
StoreWeb
TranslationApplication
RgsClientsLib
RgsCommonLibrary
RgsDatastores
RgsDiagnostics
RgsHostingFramework
RgsMatchMakingService
RgsPowershell
CpsDiagnostics
CpsHostingFramework
CpsOrbit
JoinLauncher
WebInfrastructure
Infrastructure
InternalCommon
MediaConnectivity
Media Connectivity
MediaStack_AUDIO_AGC
MediaStack_AUDIO_DRC
MediaStack_AUDIO_ECHODT
MediaStack_AUDIO_FAXDT
MediaStack_AUDIO_HEALER
MediaStack_AUDIO_NOISEDT
MediaStack_AUDIO_VAD
MediaStack_AUDIO_VSP
MediaStack_AudioCodecs
MediaStack_AudioEngine
MediaStack_COMAPI
MediaStack_COMMON
MediaStack_Crossbar
MediaStack_Crypto
MediaStack_DebugUI
MediaStack_DebugUI_AEC
MediaStack_DEVICE
MediaStack_MassConvertedTraces1
MediaStack_MediaManager
MediaStack_PerFrame
MediaStack_PerPacket
MediaStack_QualityController
MediaStack_RTCP
MediaStack_RTP
MediaStack_StreamingEngine
MediaStack_TLS
MediaStack_Transport
MediaStack_VIDEO
MediaStack_VOICEENHANCE
ApplicationSharing
Application Sharing
AsMcu
AppShareOoty
ServerTransportAdaptor
RDPApiTrace
MCUInfra
Collaboration
S4
AudioVideoConferencingIssue
Audio Video Conferencing Issue
AvMcu
AvMP
MCUInfra
Collaboration
S4
HybridVoice
Hybrid Voice
MediationServer
S4
Sipstack
OutboundRouting
TranslationApplication
IncomingAndOutgoingCall
Incoming And Outgoing Call
MediationServer
S4
Sipstack
TranslationApplication
OutboundRouting
InboundRouting
UserServices
VoiceMail
Voice Mail
Sipstack
Sipstack*
ExumRouting
InboundRouting
IMAndPresence
IM And Presence
Sipstack
UserServices
AddressBook
Address Book
ABCommon
ABServer
ABServerIISModule
Dlx
DeviceUpdate
Device Update
DeviceUpdate
DeviceUpdateHttpHandler
LYSSAndUCS
LYSS And UCS
UserServices
Lyss
McuInfra
CLS
Centralized Logging Service
CLSAgent
CLSCommon
CLSController
CLSControllerLib
SP
Support Portal
SupportPortal
SPHelper
SPModule
SPSearchTool
SPCLSTool
CLSCommon
CLSControllerLib
WAC
WAC
DataMCURunTime
DataMCU
LDM
Infrastructure
WebInfrastructure
InternalCommon
UserReplicator
User Replicator
UserServices
HostedMigration
Hosted Migration
HostedMigration
Powershell
WebInfrastructure
MonitoringAndArchiving
Monitoring And Archiving
UDCAgent
LILRLegacy
LILR Legacy
LogRetention
LegalIntercept
LILRLYSS
LILR LYSS
LogRetention
UDCAgent
MeetingJoin
Meeting Join
Collaboration
S4
UserServices
McuInfra
JoinLauncher
WebInfrastructure
Infrastructure
InternalCommon
UCWA
RGS
Response Group Service
RgsClientsLib
RgsCommonLibrary
RgsDatastores
RgsDeploymentApi
RgsDeploymentLibrary
RgsDiagnostics
RgsHostingFramework
RgsMatchMakingService
RgsPowershell
Collaboration
S4
Sipstack
CPS
Call Park Service
CpsDiagnostics
CpsHostingFramework
CpsOrbit
Collaboration
S4
Sipstack
XMPP
XMPP Gateway
XmppTGW
XmppCommonLibrary
XmppListener
XmppRouting
XmppTGWProxy
Collaboration
S4
Sipstack
CAA
Conference Auto Attendant
CAAServer
Collaboration
S4
Sipstack
UserServices

*Not sure why, but it was listed twice.



Labels:

Tuesday, June 26, 2012

WinRM QuickConfig failing with 0x8033809D

There are a few posts out there on this that point to a few different things on this error while running winrm qc.

 PS C:\Users\administrator> winrm quickconfig
WinRM already is set up to receive requests on this machine.
WSManFault
    Message = WinRM cannot process the request. The following error occured while using Negotiate authentication: An unknown security error occurred.
 Possible causes are:
  -The user name or password specified are invalid.
  -Kerberos is used when no authentication method and no user name are specified.
  -Kerberos accepts domain user names, but not local user names.
  -The Service Principal Name (SPN) for the remote computer name and port does not exist.
  -The client and remote computers are in different domains and there is no trust between the two domains.
 After checking for the above issues, try the following:
  -Check the Event Viewer for events related to authentication.
  -Change the authentication method; add the destination computer to the WinRM TrustedHosts configuration setting or use HTTPS transport.
 Note that computers in the TrustedHosts list might not be authenticated.
   -For more information about WinRM configuration, run the following command: winrm help config.

Error number:  -2144108387 0x8033809D
An unknown security error occurred.

Keep in mind what you are doing, opening WinRM via HTTP/HTTPS.  Check what your server is configured for (80 or 443, or both) and review the SPN's, and add what is needed.

To review (read only)
setspn.exe -L MACHINENAME

Review the results for HTTP/HTTPS entries (or any duplicates as well)

 Add missing names:
setspn -A HTTP/machinename
setspn -A HTTP/machinename.fqdn.com
setspn -A HTTPS/machinename
setspn -A HTTPS/machinename.fqdn.com

They reattempt your quickconfig.




Tuesday, March 27, 2012

OCS or Lync Front End not starting after patching

I have run into the issues described in this bug several times, and googling all the error messages always brings me to the Microsoft KB 968100, which has all the errors I was seeing in my OCS event log:

Event Type: Error
Event Source: Service Control Manager
Event Category: None
Event ID: 7024
Description:
The Office Communications Server Front-End service terminated with service-specific error 3287186749 (0xC3EE7D3D)
Event Type: Error
Event Source: Service Control Manager
Event Category: None
Event ID: 7022
Description:
The Office Communications Server Front-End service hung on starting.

Log Name:      Communications Server

Source:        OCS Server
Date:          7/12/2010 11:35:17 AM
Event ID:      12304
Task Category: (1000)
Level:         Error
Keywords:      Classic
User:          N/A

Computer:      ocsfe.contoso.com

Description:
The component Live Communications User Services (application: Default) reported a critical error: code C3EE7D3D (SQL server cross database chaining option is disabled for either rtc or rtcdyn database. This may be caused by attaching or restoring an existing database. Since this condition causes performance issues, service will be stopped and will not start until the problem is resolved.

Cause: Check the eventlog description.

Resolution:
Please enable cross database chaining option (using "sp_dboption '', 'db chaining', TRUE") for both rtc and rtcdyn databases and restart the service.). The service has to stop.
Additionally, the following event is logged repeatedly in the OCS log:

Event Type: Error
Event Source: OCS MCU Infrastructure
Event Category: (1022)
Event ID: 61013
Description:
The process DataMCUSvc(1692) failed to send health notifications to the MCU factory at https://ocststpool1.ned.ifo.com:444/LiveServer/MCUFactory/, 20776, 11/8/2007 3:12:41 PM.
And the following errors are logged in the OCS log at about the time that the service started encountering problems:

Event Type: Error
Event Source: OCS Server
Event Category: (1000)
Event ID: 12330
Description:
Process: 'RtcAggregate.exe' Exit Code: C3E83201
(SIPPROXY_E_SHUTDOWN_REQUESTED).
Cause: This could happen due to low resource conditions or insufficient privileges.
Resolution:
Try restarting the server. If the problem persists contact Product Support Services.
Event Type: Error
Event Source: OCS User Services
Event Category: (1006)
Event ID: 30915
Description:
Initialize failure. Failed to initialize the Service component.
Error code: C3E83201
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
After investigating the resolution in the article, (which is incorrect and doesn't have the "EXEC" in front of the command they give you) I found my databases already had the chaining option enabled. 

I did more searching, and the fix is so simple, it really should be in the KB.  You likely just patched, and you utilized the handy ServerUpdateInstaller.exe that Microsoft provides...

For example, for OCS 2007 R2 CU11, the download page here:
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=19178

The patches all worked, and you thought you were done...   until the Front End service hung on starting and dropped all the above errors in your event log.

You need to also download the OCS2009-DBUpgrade.msi and use that to update your RTC and RTCDyn Database schema to match the patches you installed.

This is done by running:
OCS2009-DBUpgrade.msi POOLNAME=pool01

Keep in mind, the poolname here is not needed to be FQDN, just the netBIOS name of the pool is needed.

Hopefully I put enough of the errors and key words in here that more people find this out with less downtime.

Labels: ,