Mickey Jervin's blog

June 5, 2009

Fixing the SharePoint Timer Service with PowerShell

Filed under: PowerShell, SharePoint — Mickey Jervin @ 11:16 am

My colleague Søren Nielsen wrote this blog post, click here, regarding fixing the Timer Service when everything breaks down.
I will not go through those bullet points, this blog post are only giving you a PowerShell script there can fix the problem automatically.

The PowerShell script:

# clear the SharePoint Timer Cache
#
#
#
# 2009 Mickey Kamp Parbst Jervin (mickeyjervin.wordpress.com)

#write program information
Write-Host -foregroundcolor White ""
Write-Host -foregroundcolor White "Clear SharePoint Timer Cache"

#**************************************************************************************
# references
#**************************************************************************************
[void][reflection.assembly]::LoadWithPartialName("Microsoft.SharePoint")
[void][reflection.assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")
[void][reflection.assembly]::LoadWithPartialName("System")
[void][reflection.assembly]::LoadWithPartialName("System.Collections")
#**************************************************************************************

#**************************************************************************************
# In this section are all the functions declared
#**************************************************************************************

#<summary>
# Stop Windows Services in a SharePoint Farm. Stop service on each "Front End" server in the farm.
#</summary>
#<param name="$winservice">An array with the Windows Services there should be restarted</param>
#<param name="$m_farm">The SharePoint farm object.</param>
function DoStopSharePointServicesInFarm
{
Param
(
[Object] $winservice,
[Object] $m_farm
)

if (-not ($m_farm -is 'Microsoft.SharePoint.Administration.SPFarm'))
{
throw '$m_farm: variable needs a farm'
}

Write-Host -foregroundcolor DarkGray ""

foreach($server in $m_farm.Servers)
{
foreach($instance in $server.ServiceInstances)
{
#if the server is a "frontend" server
if($instance.TypeName.Contains("Windows SharePoint Services Web Application"))
{
Write-Host -foregroundcolor DarkGray -NoNewline "Stop services on server: "
Write-Host -foregroundcolor Gray $server.name

foreach($winser in $winservice)
{
Write-Host -foregroundcolor DarkGray " -" $winser

Get-WmiObject -ComputerName $server.name Win32_Service -Filter "DisplayName='$winser'" | Stop-Service
}
}
}
}

Write-Host -foregroundcolor DarkGray ""
}

#<summary>
# Start Windows Services in a SharePoint Farm. Start service on each "Front End" server in the farm.
#</summary>
#<param name="$winservice">An array with the Windows Services there should be restarted</param>
#<param name="$m_farm">The SharePoint farm object.</param>
function DoStartSharePointServicesInFarm
{
Param
(
[Object] $winservice,
[Object] $m_farm
)

if (-not ($m_farm -is 'Microsoft.SharePoint.Administration.SPFarm'))
{
throw '$m_farm: variable needs a farm'
}

Write-Host -foregroundcolor DarkGray ""

foreach($server in $m_farm.Servers)</span
{
foreach($instance in $server.ServiceInstances)
{
#if the server is a "frontend" server
if($instance.TypeName.Contains("Windows SharePoint Services Web Application"))
{
Write-Host -foregroundcolor DarkGray -NoNewline "Start services on server: "
Write-Host -foregroundcolor Gray $server.name

foreach($winser in $winservice)
{
Write-Host -foregroundcolor DarkGray " -" $winser

Get-WmiObject -ComputerName $server.name Win32_Service -Filter "DisplayName='$winser'" | Start-Service

}
}
}
}

Write-Host -foregroundcolor DarkGray ""
}

#<summary>
# A list of SharePoint related services to stop
#</summary>
#<return></return>
function ListOfStopSharePointServices
{
$winServices = @()
$winServices += "Office SharePoint Server Search"
$winServices += "Windows SharePoint Services Timer"
$winServices += "Windows SharePoint Services Administration"
$winServices += "Windows SharePoint Services Search"
$winServices += "Windows SharePoint Services Tracing"
$winServices += "World Wide Web Publishing Service"

return $winServices
}

#<summary>
# remove all xml files recursive on an UNC path
#</summary>
#<param name="$m_farm">The SharePoint farm object.</param>
function DeleteXmlFilesFromConfigCache
{
param
(
[Object] $m_farm
)

if (-not ($m_farm -is 'Microsoft.SharePoint.Administration.SPFarm'))
{
throw '$m_farm: variable needs a farm'
}

Write-Host -foregroundcolor DarkGray ""
Write-Host -foregroundcolor DarkGray "Deleting xml files"

[string] $path = ""

foreach($server in $m_farm.Servers){
foreach($instance in $server.ServiceInstances){
#if the server is a "frontend" server
if($instance.TypeName.Contains("Windows SharePoint Services Web Application"))
{
#remove all xml files recursive on an UNC path
$path = "\\" + $server.name + "\c$\Documents and Settings\All Users\Application Data\Microsoft\SharePoint\Config\*-*\*.xml"
Remove-Item -path $path -Force
}
}
}

Write-Host -foregroundcolor DarkGray -NoNewline "...done"
Write-Host -foregroundcolor DarkGray ""
}

#<summary>
# clear the SharePoint cache on an UNC path
#</summary>
#<param name="$m_farm">The SharePoint farm object.</param>
function ClearTimerCache
{
param
(
[Object] $m_farm
)

if (-not ($m_farm -is 'Microsoft.SharePoint.Administration.SPFarm'))
{
throw '$m_farm: variable needs a farm'
}

Write-Host -foregroundcolor DarkGray ""
Write-Host -foregroundcolor DarkGray "Clear the cahce"

[string] $path = ""

foreach($server in $m_farm.Servers){
foreach($instance in $server.ServiceInstances){
#if the server is a "frontend" server
if($instance.TypeName.Contains("Windows SharePoint Services Web Application"))
{
#clear the cache on an UNC path
#1 = refresh all cache settings
$path = "\\" + $server.name + "\c$\Documents and Settings\All Users\Application Data\Microsoft\SharePoint\Config\*-*\cache.ini"
Set-Content -path $path -Value "1"
}
}
}

Write-Host -foregroundcolor DarkGray -NoNewline "...done"
Write-Host -foregroundcolor DarkGray ""
}

#<summary>
# A wait function there is writing a dot for each waiting second
#</summary>
#<param name="$seconds">Seconds to wait</param>
function WaitForTimerToFillCache
{
Param
(
[int] $seconds
)

#waiting a number of seconds for timer service to fill cache
$i = $seconds

Write-Host -foregroundcolor DarkGray ("Waiting " + ($i/60) + " minutes for timer service to fill cache")

#write status (the first dot on "the progress bar"
Write-Host -foregroundcolor DarkGray -NoNewline "."

while ($i -ne 1)
{
#write status (new dot for every second on "the progress bar"
Start-Sleep 1
Write-Host -foregroundcolor DarkGray -NoNewline "."
$i--
}

#write status
Write-Host -foregroundcolor DarkGray -NoNewline "...done!"
Write-Host -foregroundcolor DarkGray ""
}
#**************************************************************************************

#init the SPFarm
$farm = [Microsoft.SharePoint.Administration.SPFarm]::get_Local()

#init an array to the SharePoint Services
$winServices = @()
$winServices = ListOfStopSharePointServices

#Call the Methods for restarting the SharePoint Services
DoStopSharePointServicesInFarm $winServices $farm

#Delete all xml files from cache config folder
DeleteXmlFilesFromConfigCache $farm

#Clear the timer cache
ClearTimerCache $farm

#1st:
#Start the SharePoint Timer
$winServices = @()
$winServices += "Windows SharePoint Services Timer"
DoStartSharePointServicesInFarm $winServices $farm

#2nd:
#Wait for on the timer service to fill the cache
WaitForTimerToFillCache 120

#3rd:
#start the rest of the SharePoint Services
$winServices = @()
$winServices += "Office SharePoint Server Search"
$winServices += "Windows SharePoint Services Administration"
$winServices += "Windows SharePoint Services Search"
$winServices += "Windows SharePoint Services Tracing"
$winServices += "World Wide Web Publishing Service"
DoStartSharePointServicesInFarm $winServices $farm


How to start the PowerShell script

Like always I have a bat file there are executing the PowerShell script.

Copy the PowerShell code into a file called “ClearTimerCache.ps1”.
Place the ps1 file in a folder called “Code”

In the “root” folder create a bat file and copy following script into this.

The bat file:

%~d0
cd "%~dp0"
cd Code

Powershell.exe .\ClearTimerCache.ps1
Pause

Advertisements

May 6, 2009

Change Event Log properties with PowerShell

Filed under: PowerShell, Windows — Mickey Jervin @ 7:58 am

If you need to change the Event Log Properties like when you deploying SharePoint, here are a code snippet you can use.
In this case I need to change the properties on multiple servers on a SharePoint farm, that’s why I’m looping through the arguments of servers.
Like always I have prepared my script so I can use it on my different environments. In this case they are called (surprise) Test and Prod 😉

The bat file in Test and Prod folder are the same, but the arguments there is coming from servers.txt are different. ‘Cause the server names in Test and Prod aren’t the same…

The core PowerShell script to change Event Log properties

#gets the WMI object to change the event log
$colItems = get-wmiobject -class "Win32_NTEventlogFile" -namespace "root\CIMv2" -computername [servername]
$item = $colItems[0]

#Change the Log size
#set the "Maximum log size"
#69952*1024=71630848
$item.MaxFileSize = 71630848

# When maximum log size is reached
# If the settings should be: "Overwrite events as needed"
# $item.OverwriteOutDated = 0
# If the settings should be: "Overwrite events older than 7 days"
# $item.OverwriteOutDated = 7
$item.OverwriteOutDated = 0

# Make it happen
$item.Put("&h20000")

The result:
Before
before

After
after

File and folder structure:

Normally I have my files and folders like this

<cut on>
\PowerShell\
\PowerShell\code
\PowerShell\code\EventLog.ps1
\PowerShell\prod1_EventLog.bat
\PowerShell\prod\servers.txt
\PowerShell\test1_EventLog.bat
\PowerShell\test\servers.txt
<cut off>

Folder function:
\PowerShell
This folder is the root folder

\PowerShell\code
This folder contains the PowerShell files

\PowerShell\prod
This folder contains the executable bat file and a file to the specific environment stuff for the Production environment

\PowerShell\test
This folder contains the executable bat file and a file to the specific environment stuff for the TEST environment

File comments
The 01_EventLog.bat is the same but copied twice because of the servers.txt file
The servers.txt files have different content regarding the environment
The EventLog.ps1 contains the custom PowerShell code

\PowerShell\Code\EventLog.ps1
<code on>
# Change Event Log
#
#
# 2009 Mickey Kamp Parbst Jervin (mickeyjervin.wordpress.com)

if( $args.length -eq 0 ){
write-error "Usage: EventLog.ps1 server1 [server2 […] ]"
exit
}

foreach( $server in $args ){
#write servername to change eventlog properties
Write-Host -foregroundcolor White “Eventlog (” $server “)”

#gets the WMI object to change the eventlog
$colItems = get-wmiobject -class “Win32_NTEventlogFile” -namespace “root\CIMv2” -computername $server

$item = $colItems[0]

$item.MaxFileSize = 71630848
$item.OverwriteOutDated = 0
$null = $item.Put("&h20000")
}
<code off>

\PowerShell\[Environment]1_EventLog.bat
<code on>
echo off

%~d0
cd “%~dp0”

set file=servers.txt

set servers=

for /f “tokens=*” %%a in (‘type %file%’) do set servers=%%a

rem echo %servers%

cd ..
cd Code

Powershell.exe .\EventLog.ps1 %servers%

pause
<code off>

\PowerShell\[Environment]\Servers.txt
<code on>
server1 server2 server3
<code off>

May 4, 2009

Read xml from PowerShell

Filed under: PowerShell — Mickey Jervin @ 11:32 am

I just love reading xml from PowerShell. It could be so hard in VBScript and all those lines of code…

But in PowerShell you just do like this:
[xml]$list = [XML]$(Get-Content C:\PowerShell\WinServices\Code\SharePointServicesConfig.xml)

And now you simply dot you through your xml document
$list.WindowsServices.SharePointService

Thanxx alot 🙂

Result:

The xml file – SharePointServicesConfig.xml

<code on>
<WindowsServices>

<SharePointService Name=”Office SharePoint Server Search” />

<SharePointService Name=”Windows SharePoint Services Timer” />

<SharePointService Name=”Windows SharePoint Services Administration” />

<SharePointService Name=”Windows SharePoint Services Search” />

<SharePointService Name=”Windows SharePoint Services Tracing” />

<SharePointService Name=”Windows SharePoint Services VSS Writer” />

<SharePointService Name=”World Wide Web Publishing Service” />

</WindowsServices>
<code off>

Older Posts »

Blog at WordPress.com.