Marc posted on January 5, 2009 08:41

All product based on SharePoint technologies come with a built-in logging engine named Unified Logging System (ULS). It allows the applications and related component (Microsoft or third-parties) to log activity to the Windows application Event Log and/or to a log file on each server running SharePoint.

Log Location

The log files are, by default, located under C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\LOGS, the file names always start with a prefix consisting in the name of the server they were generated on: <servername>-<output-format>.log.

Depending upon their configuration, some event may also be logged in the Windows Application event log.

Configuration

To change the location of the log files, the following PowerShell script can be used:

[VOID][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[VOID][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")
$SPDiagnosticsService = [Microsoft.SharePoint.Administration.SPDiagnosticsService]::Local
$SPDiagnosticsService.LogLocation = "G:\Logs\"
$SPDiagnosticsService.Update()

To change the number of log files to be maintained, you can set the “LogsToKeep” property:

$SPDiagnosticsService.LogsToKeep= 24
$SPDiagnosticsService.Update()

Beware: as soon as the Update() method is invoked, the log files above the value specified will be deleted!

Note: this correspond to the setting stored in the registry at the following location: HKLM:\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\WSS. You might therefore therefore be tempted to edit it directly but MS discourage to do so and recommended to use the SharePoint API instead.

To list/set the verbosity level of each component, STSADM can be used:

To list all level (including hidden ones): stsadm.exe -o listlogginglevels [-showhidden]

To set the level for a given category: stsadm.exe -o setlogginglevel   [-category < [CategoryName | Manager:CategoryName [;...]] ] {-default | -tracelevel < trace level setting> [-windowslogginglevel] <Windows event log level setting>}

More information:

Log File Format

The log files expose the following fields:

  • Timestamp: Equivalent to the “TimeGenerated” field in the “Application” event Log
  • Process: the image name of the process logging its activity followed by its process ID (PID) between parentheses. Interestingly, IIS worker processes may also log their activity, they are therefore logged under w3wp.exe
  • TID
  • Area: This maps the “Source” field in the “Application” event Log
  • Category: this maps the “Category” field in the “Application” event Log
  • EventID: A unique internal Event ID
  • Level
  • Message
  • Correlation: may contain a link to the the EventID of another logged event

Exploitation/Analysis

There are multiple ways to analyze ULS logs, such as:

Some Log Parser Queries applicable to ULS Logs

More Information

And cut!


Posted in: Logging , LogParser , PowerShell , SharePoint  Tags:
Marc posted on December 31, 2008 04:47

With the early days of SharePoint, changing user accounts in order to reflect user changes in Active Directory after domain migration, migration or split  was a nightmare.
With WSS2/SPS2003 and assuming you have compiled the excellent SPSUTIL tool , the situation was much better though not perfect (Anthony, the other Windows Director, suffered a lot from this in a previous job actually, who did not?).

With the WSS3/MOSS era, STSADM now comes with the built-in command “–o migrateuser” in order to do the job. So why bother turning this command into PowerShell? Simply because it greatly eases the automation since you can write custom scripts to scan AD, parse XML or CSV and finally update your SharePoint content DB’s accordingly. The code is incredibly simple, just like the command is:

First, load the assemblies as usual:
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")

Then get a farm object:
$spFarm = [Microsoft.SharePoint.Administration.SPfarm]::Local

And finally use the
$spFarm.MigrateUserAccount("OLDDOMAIN\OLDUSERNAME", "NEWDOMAIN\NEWUSERNAME", $False)

The first parameter being the original domain name and user name
The second parameter is the new domain name\user name
And the third is Boolean indicating sidhistory on the new user should be used or not.

Keep in mind that while this code will modify the “Account” attribute of a user through the farm, it will not change the “Name” attribute. %If you wish to change this name and you’re lucky enough to operate MOSS, you can rely on the profile import process (see my previous post for some Powershell automation), if, on the other hand, you run WSS3, you’ll have to go through extra code that does some iterations in all your sites and modify the contents of the list named “User Information List” in each of them. The Powershell to update the list would look like:
$spUser = $spWeb.SiteUsers["NEWDOMAIN\NEWUSERNAME"]
$spUser.Name = "NEW USER DISPLAY NAME"
$spUser.Update()

A good movie match for this post could be Face/Off directed by John Woo, the "unofficial inventor" of slow motion.

Face/Off Poster

And cut!


Posted in: AD , PowerShell , SharePoint  Tags:

Sometimes AD is not the preferred source for profiles information. Sometimes you feel like BDC is really a pain to configure. Sometime a colleague of yours comes with a plain CSV file which contains the perfect information in order to update your MOSS user profile information… Time for Jason to recover his identity ;)

Bourne Identity poster

First, let’s load the necessary assemblies:
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.Administration")
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles")

Then instantiate the server context and the profile manager
$spSSP = [Microsoft.Office.Server.ServerContext]::GetContext(“MySSPName”)
$spUserManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($spSSP)

Note: if you have no clue about the name of the SSP, you can check in the Central Admin web site or retrieve it from an existing web application bound to it.

Now that you have a Profile manager ready, you have to create a Profile object for each profile you wish to update. Since the code would eventually fails if no profile exists, you can also test if it exists first:
$spUserManager.UserExists("THREADSTONE\jbourne")
If it result returns “True”, you can go further, if not, you can skip that user or instead, create a new profile by executing:
$spUserManager.CreateUserProfile("THREADSTONE\jbourne ")

Then instantiate a profile object for that user:
$spUserProfile = $spUserManager.GetUserProfile("THREADSTONE\jbourne ")

And populate one or more properties:
$spUserProfile["Department"].Value = "Secret Services"

If you’re clueless about the list of properties you can update, simple retrieve them with the following command:
$spUserManager.Properties|SELECT displayName,Name

Once you’re done, save the changes using the commit method (and not update()!):
$spUserProfile.Commit()

And cut!

Greets to W. N. who inspired this post ;)


Posted in: PowerShell , SharePoint  Tags:

Nothing new here, just a repost by popular demand... 
Many examples on the Internet show how to use the Office Automation COM object to achieve this. But under some circumstances, this is not possible because Excel is simply not installed locally.


Lets instantiate the objects we need:
$OleDbConn = New-Object "System.Data.OleDb.OleDbConnection"
$OleDbCmd = New-Object "System.Data.OleDb.OleDbCommand"
$OleDbAdapter = New-Object "System.Data.OleDb.OleDbDataAdapter"
$DataTable = New-Object "System.Data.DataTable"


Set the connection string and connect. Please pay attention to the syntax, otherwise, you’ll get cryptic errors such as “Could not find installable ISAM”. Also, the file should not be locked exclusively
$OleDbConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\lognoulm\Desktop\servercfg.xls;Extended Properties=""Excel 8.0;HDR=YES"""
$OleDbConn.Open()


Optionally, to check that the connection is open, display the “State” property:
$OleDbConn.State


Now let’s construct a SQL query. Syntax for Excel is a little special, look at the end of this post for external references.
$OleDbCmd.Connection = $OleDbConn
$OleDbCmd.CommandText = "SELECT * FROM [Sheet1$]"


Then set the Adapter object
$OleDbAdapter.SelectCommand = $OleDbCmd


And then fill the DataTable object with the results
$OleDbAdapter.Fill($DataTable)


If everything went fine, the command above will return the number of row present is the DataTable object. To display the “raw” contents, just enter
$DataTable


To show the first line (aka Row), use this $DataTable.Rows[0]
And how to display a given field in that row? Just use the field header. In my XLS, one header is for example “Name”
$DataTable.Rows[0].Name

More information can be found here:

Note: This was not tested using an XLSX files but with a standard XLS instead
Note 2: DataSet can be used instead of DataTable object but I prefer this one in favor of greater simplicity (this is to be used by sysadmins, not developersJ)
Note 3: I blogged about reading but you can update and insert too, see references above for details

And cut!


Posted in: PowerShell , Office  Tags:

Nothing new here, just a repost by popular demand... 

We need an SMTP Client object and a Mail Message object:

$SmtpClient = new-object system.net.mail.smtpClient

$MailMessage = New-Object system.net.mail.mailmessage

Then a basic configuration of their properties (you may have to adapt to fit you environment’s needs)

$SmtpClient.Host = "mysmtpserver.mycompany.local"

$mailmessage.from = "notification-services@mycompany.local"

$mailmessage.To.add("itadmins@mycompany.local")

$mailmessage.Subject = “Daily Uptime Reports”

$mailmessage.Body = “Server01. mycompany.local: 99.999% uptime”

And now, the special touch that makes Outlook display the message with a “bell” icon à la SharePoint notification:

$mailmessage.Headers.Add("message-id", "<3BD50098E401463AA228377848493927-1>") 

All you need is to add 3BD50098E401463AA228377848493927 before the actual message ID and separate them with a dash  And then send the message

$smtpclient.Send($mailmessage)

If you want your email to look even more eye-candy, enabled and add HTML to the body before sending

$mailmessage.IsBodyHtml = 1

You can even read from a file using get-content and generate the body

$mailmessage.Body = Get-Content .\report.html

Find more information over here:

And cut!


Posted in: PowerShell , Messaging  Tags:
Disclaimer
The information of this site is provided "AS IS" with no warranties, and confers no rights. This site does not represent the thoughts, intentions, plans or strategies of our employers, customers, friends or family. It is solely our own personal opinions. All code samples, scripts or configuration files are provided "AS IS" without warranty of any kind.

Limite de respnsabilité
Le contenu de ce site est délivré "TEL QUEL" et ne confère aucun droit ni garantie. Ce site ne reflète en aucun cas les pensées, intentions, projets ou stratégies de nos employeurs, clients, amis ou membre de nos familles. Il est uniquement l’expression de nos opinions personnelles. Les échantillons de codes, scripts ou fichiers de configuration sont fournis "TEL QUEL", sans la moindre garantie d’aucune sorte.