Truncate (Shrink) LOG Files of Databases in SQL Server 2008 R2

Today I got this error while trying to shrink my SharePoint 2010 databases on my dev machine:

‘TRUNCATE_ONLY’ is not a recognized BACKUP option.

I searched for the error and found different sites, e.g.:

But there was no complete script for “truncating” all of my databases  at once.

Here is my script:

[sourcecode language=”sql”]–TRUNCATE_LOG for all databases at once on SQL SERVER 2008 R2
–https://blog.kenaro.com/2011/08/28/truncate-shrink-log-files-of-databases-in-sql-server-2008-r2/

DECLARE c CURSOR FOR SELECT database_id, name, recovery_model_desc FROM sys.databases — WHERE name=’sharepoint_config’; 
DECLARE @dbname VARCHAR(1024); 
DECLARE @rmod VARCHAR(1024); 
DECLARE @id INT; 
DECLARE @lfile VARCHAR(1024);  

OPEN c;  

FETCH NEXT FROM c INTO @id, @dbname, @rmod; 

WHILE @@FETCH_STATUS = 0 
BEGIN
IF @rmod = ‘FULL’
BEGIN
SET @lfile = (SELECT name FROM sys.master_files WHERE database_id = @id AND type=1)
PRINT @lfile
EXEC(‘ALTER DATABASE [‘ + @dbname + ‘] SET RECOVERY SIMPLE’)
EXEC(‘USE [‘+@dbname+’]; DBCC SHRINKFILE([‘+@lfile+’], 1)’)
EXEC(‘ALTER DATABASE [‘ + @dbname + ‘] SET RECOVERY FULL ‘)
END ELSE
IF @rmod = ‘SIMPLE’
BEGIN
SET @lfile = (SELECT name FROM sys.master_files WHERE database_id = @id AND type=1)  
PRINT @lfile
EXEC(‘USE [‘+@dbname+’]; DBCC SHRINKFILE([‘+@lfile+’], 1)’)
END
FETCH NEXT FROM c INTO @id, @dbname,@rmod; 
END;  

CLOSE c 
DEALLOCATE c  
[/sourcecode]

For me it works like expected.

“LongPathSupport”: Operate with files and directories with “long paths” in .NET (CodePlex Project)

In my project RoboPowerCopy (http://robopowercopy.codeplex.com) I’ve implemented a basic set of classes and methods for use with files and directories with long paths. NTFS supports paths with up to 32000 characters. But .NET only supports 256 characters. So System.IO.FileInfo and System.IO.DirectoryInfo will not work with such a file:

c:usersikarsteinappdatalocal111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000hello.txt

This path has 655 characters. No way in .NET without using the Win32 API.

I’ve wrapped the API calls into a set of basic .NET classes to provide a basic support for files and directors with long paths…

Here it is: http://longpathsupport.codeplex.com

Please feel free to contribute the project or post you experiences on my blog or on Codeplex!

For the project I’ve read/used some other source in the Internet. Especially this three I’d like to refer to:

Walkthrough: Deploy ClickOnce Application as SharePoint 2010 Solution Package

In some projects there was a need to run code on the client machine for interaction with SharePoint. If’ve realized this kind of applications as “ClickOnce” apps. It’s possible to deploy them as “SharePoint Solution Package”. If you do so the ClickOnce files can be deployed to every WFE. Updating the ClickOnce is easy.

Here I want to show you how to deploy a ClickOnce app als SharePoint Solution.

Let’s start.

1. Create your ClickOnce app. – If you have an existing one skip to step 5. – Otherwise continue reading. I’ll show you how to create a very simply ClickOnce.

Open  Visual Studio 2010. Create a new project of type “Windows Forms Application” or “WPF Application”. I’ll use the first one and name the project “MyClickOnce”.

image

Design you app. – I drag 2 Label controls, 2 Checkbox controls and 2 Textbox controls to the surface. I do not change their names but their fonts Smile

image

In my app I’d like to show the “running context”: locally started EXE or online started ClickOnce. Furthermore I’d like to show the URL if started online.

2. Open the Code view of the form.

First of all you need to add a assembly reference for “System.Web”!

Then insert this code. Maybe you need to correct the name of the controls.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.Deployment.Application;
using System.Web;

namespace MyClickonce
{
    public partial class Form1 : Form {
        public Form1()
        {
            InitializeComponent();

            ParseParams();

            checkBox1.Checked = !IsOnline;
            checkBox2.Checked = IsOnline;
            textBox1.Text = Url;
            textBox2.Text = Parameters["Param1"];
        }

        private bool _isOnline = false;
        private NameValueCollection parameters = null;
        private string _url = "";

        public bool IsOnline
        {
            get {
                return _isOnline;
            }
        }

        public string Url
        {
            get {
                return _url;
            }
        }

        public NameValueCollection Parameters
        {
            get {
                return parameters;
            }
        }

        private void ParseParams()
        {
            NameValueCollection nameValueTable = new NameValueCollection();

            if( ApplicationDeployment.IsNetworkDeployed )
            {
                _isOnline = true;
                _url = ApplicationDeployment.CurrentDeployment.ActivationUri.ToString();

                string queryString = ApplicationDeployment.CurrentDeployment.ActivationUri.Query;
                parameters = HttpUtility.ParseQueryString(queryString);
            }
            else {
                _isOnline = false;
                parameters = HttpUtility.ParseQueryString(string.Join("&", Environment.GetCommandLineArgs()));
            }
        }
    }
}

The method “ParseParams” will be useful while developing the app and later running the app: This method is able to parse both “command line parameter” sources: URL and native (EXE). During development you maybe need to pass parameters to the app for testing purpose. Than you define this parameters in the “Debug” tab of the project properties.

Here is a screenshot of the app’s debug settings:

image

You see there is a parameter “Param1” follwed by “=” and it’s value. This is similar to URL style query string parameters. But you do not separate them with “&”! Instead use a single whitespace. – Later in the URL you will use “&” as normal!

Now just run the app!

image

Nice, isn’t it?

3. Now you need to configure the application to become a ClickOnce.

Open the Project Properties of your Windows Form App project.

Select the “Signing” tab and create a self signed certificate. Or use a valid Code Signature certificate.

image

Now switch to the “Publish” tab of the project settings.

Here you can change the settings as you need it. – I’ll leave it as is EXCEPT one setting: Click the “Options…” button and select “Manifests”. Check “Allow URL parameters to be passed to application”:

image

[If you do not set this the app will fail in the following line because “ActivationUri” will be null: “_url = ApplicationDeployment.CurrentDeployment.ActivationUri.ToString(); “]

The other settings:

image

Click “Publish Now”.

Than the project will be build and stored to the sub folder “Publish” of your project folder in the file system.

image

4. If you now try to run the app locally you may get this error:

image

This is caused by your ClickOnce publishing in the step before.

The resolve this open the project settings, select the “Security” tab and clear the checkbox “Enable Clickonce security settings”:

image

This you need to do after each ClickOnce publishing!

5. Now we create the SharePoint Solution Package.

In the Solution Explorer click on the solution item, click “Add” and click “New project”.

image

Now chooce “Empty SharePoint Project” and name it “MyClickonceDeployment”.

As local site I use “http://sharepoint.local/sites/clickonce”. It has to be a “Farm Solution”!!

image

Now create a “Module” project item. Name it “MyClickonce”.

SNAGHTMLacb2fc

Remove the file “Sample.txt”

image

6. Now open the solutions path in Windows Explorer.

Go into the folder of the Windows Forms Application. There go into the “Publish” folder.

Select the “.application” file of your ClickOnce app and select the “Application Files” folder. This items you need to copy. Just select “Copy” from the context menu or press Ctrl+C.

No open the folder of “MyClickonceDeployment” and go into the folder “MyClickonce”. There insert (paste) the selected items.

Now you folder should look like this:

image

In the “Application Files” folder you’ll see another folder “1_0_0_0” or with another version number. This version number will be increased by every ClickOnce publishing if you did not disable this function.

7. Back in the Visual Studio go into the Solution Explorer and click this icon:

image

This will show you all files in the project folder, not even project items.

Select the “MyClickonce” module project item. Maybe you need to click the icon:

image

You should see this:

image

Right click on “MyClickonce.application” and select “Include in project”. Right click on “MyClickonce_1_0_0_0” and select “Include in project”.

Now you need to edit the “Elements.xml” file of you module project item.

First of all add an attribute named “Path” to the “Module” tag. This will define the URL of your ClickOnce app. Select a unique name so that the solution won’t get in conflict with other solutions. You could choose a GUID here or use date and time:

image

Now you can remove the string “MyClickonce/” of the beginning of every “Path” attribute of the child nodes of the “Module” tag.

image

After removing the string the file should have this content:

<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <Module Name="MyClickonce" Url="MyClickonce20110815152200"> <File Path="MyClickonceMyClickonce.application" Url="MyClickonce.application" /> <File Path="MyClickonceApplication FilesMyClickonce_1_0_0_0MyClickonce.application" Url="Application Files/MyClickonce_1_0_0_0/MyClickonce.application" /> <File Path="MyClickonceApplication FilesMyClickonce_1_0_0_0MyClickonce.exe.deploy" Url="Application Files/MyClickonce_1_0_0_0/MyClickonce.exe.deploy" /> <File Path="MyClickonceApplication FilesMyClickonce_1_0_0_0MyClickonce.exe.manifest" Url="Application Files/MyClickonce_1_0_0_0/MyClickonce.exe.manifest" /> </Module> </Elements> 

8. Now deploy your SharePoint Solution Package!

9. To verify the ClickOnce was deployed correctly just open the site with SharePoint Designer 2010.

Open SPD.

Click “All Files”.

Now you should find your folder “MyClickonce20110815152200”.

image

9. Open the SharePoint site you deployed to.

Enter the complete URL of the ClickOnce app in the address bar of the browser. In my case the URL is:

http://sharepoint.local/sites/Clickonce/MyClickonce20110815152200/MyClickonce.application

image

Open the URL.

The ClickOnce should start after some seconds. During installation or update you’ll see these windows:

image

image

It will look like this:

image

10. Now lets add a Quicklaunch entry for this:

image

In the link I’ve used “Param1”: http://sharepoint.local/sites/Clickonce/MyClickonce20110815152200/MyClickonce.application?Param1=Hey, Ingo!

image

Just click the Quicklaunch entry.

You’ll get:

image

That’s it. – Please let me know if it worked for you!

Of course you could build query strings in JavaScript to pass dynamically generated parameters to the ClickOnce!! This is charming and makes ClickOnce apps to become usefull in SharePoint development. You could create custom Ribbon menu items and call a ClickOnce app on click. As parameters you could pass ListID, Web URL, ItemID, … to the app! Very cool!

Have fun! – Please post your comments on this!

SharePoint PowerShell Timer Jobs: Run PowerShell scripts in SharePoint Timer Service context.

I’ve created a new project that combines my two primary technical passions: SharePoint 2010 and PowerShell. Smiley

The project “SharePoint PowerShell Timer Jobs” lets you create, modify and delete SharePoint timer jobs that run PowerShell scripts in the context of the SharePoint Timer Service!

It’s on Codeplex – including source code:

I hope you will love it! (If so please let me know!) – Please feel free to extend the project. If you do so please share your extensions with the community!!!

PowerShell Timer Jobs could be very useful. I’ll use it for “SharePoint Warmup”. Therefore I create a PowerShell script some months ago. This I will port to a PowerShell Timer Job and post it on my blog…

 

Now let’s have a look…

 

Here’s a screenshot of the “System Settings” page of the SharePoint 2010 Central Administration:

pic01

Use “Manage PowerShell Jobs” to create, modify or delete PowerShell jobs.

On the admin page you can select an existing timer job or select “<new>” to create a new one.

If you create a new one you have to configure it and name it. Then save the timer job. After that you’ll be able to edit the script.

In this screenshot you see an existing timer job:

Here the “Edit” button is enabled. The script below the “Edit” button is read only!

Click “Edit”… Here is what you will see:

In the Edit dialog you can enter your PowerShell script and save it.

The Edit dialog does not validate your script! It have to be valid. Or you will see errors in the history list.

At the management page you can enable or disable existing jobs using the checkbox. Don’t forget to click the “Update” button after you changed something!

At the “System Settings” page of the Central Administration you see the link “Review PowerShell Job Execution History”. Using this link you will be redirected to the history list. All outputs of all of your PowerShell jobs will be collected here.

The list will not be cleared automatically! – But… You could create a SharePoint PowerShell Timer Job for this purpose 🙂 …

The last thing you should know: All the jobs you create are accessible at common SharePoint Job admin pages  like “Review Job definitions” and “Check job status” (Central Administration -> Monitoring)

Here you see a screenshot of the “Review Job definitions” page of SharePoint 2010:

This is a screenshot of the Job definitions detail page:

At least a screenshot of the “Check job status” page of SharePoint:

Some more details…

The PowerShell script of each timer job will be executed in a dedicated PowerShell runtime environment (“Runspace”).

For the PowerShell runspace I’ve created a PowerShell Host implementation. This implementation does not support any user interaction! Be sure your script does not need to interact with the user, e.g. for delete confirmation.

The script you enter will be surrounded with this code:

Add-PSSnapIn Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue | out-null  
$o = Invoke-Command -ScriptBlock 
{ 
<your code> 
} 
$p = $o | out-string 
$p
 

For script development you should use this code frame too! But if you copy the script code from the development tool, e.g. Windows PowerShell ISE, to PowerShell Timer Jobs, be sure only to copy <your code>.

Furthermore you need to enable the execution of unsigned PowerShell scripts in the context of the SharePoint Timer Service. This service normally runs under the Farm account. Have a look into the “Services” management console.

Before you use the tool be sure you know what you do! – PowerShell scripts can damage your farm! BE CAREFULL!!!!I’m not responsible for any damages.

You shoud test the tool in your own environment. There could be errors in the tool!!! I’ve tested it in my dev environment, but maybe in yours it does not work properly!

Feel free to extend the tool. But if you do so please publish your code to the community.

You must not remove my name or the link to the projects homepage from any file or page of the project. – Please don’t do that. Thanks 🙂

 TO USE THE PROJECT…

…you need to deploy the .WSP file to sharepoint and activate the SharePoint features in the Central Administration. The history list have to resist on the CA!!!

SharePoint Warm Up – Now with “Timeout”

In January 2011 I published a SharePoint Warm Up script based on PowerShell.

Some days ago blog reader Tamas published an comment: https://blog.kenaro.com/2011/01/27/sharepoint-warm-up-with-powershell/#comment-286

“How to set a connection timeout”.

 

Here we go now!

 

I’ve extended the Warm Up Script. I hope, this helps some of you, especially Tamas Smiley

# SharePoint Warmup Script
# by Ingo Karstein
# 2011/01/26
# 2011/08/02

#<---- Improvement starts here
#region MyWebClient
    Add-Type -ReferencedAssemblies "System.Net" -TypeDefinition @"
    using System.Net;

    public class MyWebClient : WebClient
    {
        private int timeout = 60000;
            
        public MyWebClient(int timeout)
        {
            this.timeout = timeout;
        }
        
        public int Timeout
        {
            get
            {
                return timeout;
            }
            set
            {
                timeout = value;
            }
        }
        
        protected override WebRequest GetWebRequest(System.Uri webUrl)
        {
            WebRequest retVal = base.GetWebRequest(webUrl);
            retVal.Timeout = this.timeout;
            return retVal;
        }
    }
"@
#endregion
#----> Improvement ends here

$urls= @("http://sharepoint.local", "http://another.sharepoint.local")

New-EventLog -LogName "Application" -Source "SharePoint Warmup Script" -ErrorAction SilentlyContinue | Out-Null

$timeout = 60000 #=60 seconds               #<--- Improvement!

$urls | % {
    $url = $_
    try {
        $wc = New-Object MyWebClient($timeout)        #<--- Improvement!
        $wc.Credentials = [System.Net.CredentialCache]::DefaultCredentials
        $ret = $wc.DownloadString($url)
        if( $ret.Length -gt 0 ) {
            $s = "Last run successful for url ""$($url)"": $([DateTime]::Now.ToString('yyyy.dd.MM HH:mm:ss'))" 
            $filename=((Split-Path ($MyInvocation.MyCommand.Path))+"lastrunlog.txt")
            if( Test-Path $filename -PathType Leaf ) {
                $c = Get-Content $filename
                $cl = $c -split '`n'
                $s = ((@($s) + $cl) | select -First 200)
            }
            Out-File -InputObject ($s -join "`r`n") -FilePath $filename
        }
    } catch {
          Write-EventLog -Source "SharePoint Warmup Script"  -Category 0 -ComputerName "." -EntryType Error -LogName "Application" `
            -Message "SharePoint Warmup failed for url ""$($url)""." -EventId 1001

        $s = "Last run failed for url ""$($url)"": $([DateTime]::Now.ToString('yyyy.dd.MM HH:mm:ss')) : $($_.Exception.Message)" 
        $filename=((Split-Path ($MyInvocation.MyCommand.Path))+"lastrunlog.txt")
        if( Test-Path $filename -PathType Leaf ) {
          $c = Get-Content $filename
          $cl = $c -split '`n'
          $s = ((@($s) + $cl) | select -First 200)
        }
        Out-File -InputObject ($s -join "`r`n") -FilePath $filename
    }
}