25 Okt 2013

DateDiff and DateAdd Excluding Weekends in SQL Script

Have you ever wonder how to count date differences and add date, but excluding weekends (Saturday and Sunday)? I stumbled on these 2 functions, which I prefer best to do the operation.


CREATE FUNCTION [VARS].[FN_DateAddBusinessDay]
(
    @InputDate DATETIME = NULL,
    @InputDays INT
)
RETURNS DATETIME
AS
BEGIN
    -- Declare the return variable here
    DECLARE @OutputDateTime DATETIME
    DECLARE @date DATETIME
    DECLARE @days INT
    DECLARE @weeks INT
    DECLARE @i INT = 0
    -- Add the T-SQL statements to compute the return value here
    SET @date = @InputDate
    SET @days = @InputDays
    IF @days >= 1
    BEGIN
        SET @days = @days - 1
    END
    
    IF DATENAME(dw, @date) = 'Saturday'
    BEGIN SET @i = 2 END
    ELSE IF DATENAME(dw, @date) = 'Sunday'
    BEGIN SET @i = 1 END
    SET @date = DATEADD(d, @i, @date)
 
    IF (@days < 0)
    BEGIN
        IF DATEPART(dw, @date) = 1
            SET @date = DATEADD(d, -1, @date)
        SET @weeks = (datepart (dw, @date) + @days - 6)/5
    END
    ELSE
    BEGIN
        IF DATEPART(dw, @date) = 7
            SET @date = DATEADD(d, 1, @date)
        SET @weeks = (DATEPART(dw, @date) + @days - 2)/5
    END    -- Return the result of the function
    SET @OutputDateTime = DATEADD(d, @days + (@weeks * 2), @date);
    RETURN @OutputDateTime;
 
END
 
GO


CREATE FUNCTION [VARS].[FN_DateDiffBusinessDay]
(
    @InputStartDate DATETIME = NULL,
    @InputEndDate DATETIME = NULL
)
RETURNS INT
AS
BEGIN
    -- Declare the return variable here
    DECLARE @OutputDays INT
    DECLARE @date DATETIME
    DECLARE @days INT
    DECLARE @weeks INT
    -- Add the T-SQL statements to compute the return value here
    IF DATEDIFF(DD, @InputStartDate, @InputEndDate) >= 0
    BEGIN
        SET @OutputDays = (SELECT
           (DATEDIFF(dd, @InputStartDate, @InputEndDate) + 1)
          -(DATEDIFF(wk, @InputStartDate, @InputEndDate) * 2)
          -(CASE WHEN DATENAME(dw, @InputStartDate) = 'Sunday' THEN 1 ELSE 0 END)
          -(CASE WHEN DATENAME(dw, @InputEndDate) = 'Saturday' THEN 1 ELSE 0 END))
    END
    ELSE
    BEGIN
        SET @OutputDays = 0
    END
    RETURN @OutputDays;
 
END

Enjoy, and hope it helps! Winking smile

24 Apr 2013

Named String Format in C#

It is nice on how NET Framework gave a bunch of “shortcut” code, including String.Format. But we have to keep track of the indices in the object array which is not really nice.

82653205

It would be good if we just write code, declare a named string collection and format it.

  1. string format = "my name is [[name]] for it called [[name]] to be noted. and address is [[address]].";
  2. Hashtable ht = new Hashtable() { { "name", "Minion No. 10594" }, { "address", "gru's place" } };
  3. txtResult.Text = format.Format(ht);

Now we can use my commonly-used library in rdz.codeplex.com, and use the Format method in StringUtility class. You can download it and use it.

Don’t forget to add reference to Rdz.dll and put using directive as below. You are good to go and the Format function will be available on every string object, like in the example above.

  1. using Rdz.Utility;

In case you didn’t notice, the hashtable is case-sensitive. So to make it case-insensitive, declare Hashtable as below.

  1. Hashtable ht = new Hashtable(StringComparer.CurrentCultureIgnoreCase) { { "name", "Minion No. 10594" }, { "address", "gru's place" } };

Cool! See you! Winking smile

Important Command-Line for Developers

There some bunch of tools which we never know that will help us in our daily operations as developer. But I’ll give you some of that.

Generate Web-Service Proxy Class from WSDL

Generating proxy class from WSDL is important if you want to get data from multiple web services containing exactly the same method. So, in the end you can use the class, set the URL and call the method simultaneously with other URLs.

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\WSDL.exe" /out:"<path to cs file>\<cs filename>.cs" /n:<namespace> http://<complete URL to WSDL>/<WebServiceName>.asmx?wsdl

Generate XSD from XML

Generating XSD can be done by using XSD.exe file located in Microsoft SDKs.

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\XSD.exe" "<path to xml file>\<xml filename>.xml"

Generate Class from XSD

Generating Class from XSD also useful in many ways. There are 2 type of class, the one which we can use as dataset, and the one just plain class to use to read Xml. So if you want to deserialize an XML and put it on your code, definitely you will need to convert XML to XSD, and XSD to Class.

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\XSD.exe" /language:CS /classes /n:<namespace> "<path to XSD file>.xsd"

6 Apr 2013

Attach SQL Database from Network Drive

One crazy question came up in mind, can I attach a database from network drive? There’s a lot of recommendation, that we can’t attach SQL Database. Why would we want it? Anyway no one would do that, unless they want a little bit hiccup in their system and mess up the whole thing? That’s true, but I want a solid answer. Can it be done?

The answer is it can be done. But again, on really strict rules, this is not recommended. Why would I want it? Because I have development VM (VirtualBox) and I need those big databases (say about ~20GB) to be exist on my system without copying it inside my Virtual Hard Disk which will take some time to copy. Again, it’s a development VM, so I could manage it and no one would care if my system crashed or database not exist.

So, here it is.

Attach Database from Network
  1. -- this command to turn on network share attach DB
  2. DBCC TraceOn(1807)
  3. -- attach it
  4. EXEC sp_attach_db @dbname = N'WSS_Content_85',
  5.    @filename1 = N'\\Vboxsvr\r\DOCS\SQL Database\WSS_Content_85.mdf',
  6.    @filename2 = N'\\Vboxsvr\r\DOCS\SQL Database\WSS_Content_85_log.ldf'
  7. -- this command to turn off network share attach DB
  8. DBCC TraceOff(1807)

Please do note that this command would likely not recommended, especially on production server. Thanks to Sumardi Soemartopo for blogging about this COOL tips, and this is the link to that page http://guozspace.wordpress.com/2009/02/26/microsoft-sql-server-how-to-attach-database-from-network-drive/.

13 Mar 2013

Assign a User to Manage SharePoint User Profile

Maybe in some of particular scenario, we found that the user wanted to manage user profile alone without using Farm Administrator Account and to keep the user with a minimal security access.

That way, we can configure User Profile Service Application to have particular user granted as User Profile Manager. So they can go to Central Administration website without touching other configuration.

How we can do this?

8 Mar 2013

Xml: Another Way to Use Configuration Options

Many developers believe, a good way to save configuration, can save another line of code. So do I, do not like complicated code to just saving a configuration options for an application that I’ve made. Can’t say how many methods out there to save configuration options, as this is not limited to creativity of each person.

E014584

I do have one way, which is simple enough for me to save any type of configuration with almost any kind of data type. Xml is one of the many options and to do that we just need 2 methods, serialize and deserialize.

28 Feb 2013

Visual 2010 Macro: Automate “Attach to Process” to IIS Worker Process (w3wp.exe)

If you take a look at my post a few months ago about my own development environment, maybe you didn’t notice that I posted a link to a macro. This macro I’ve created myself to help me build SharePoint solutions faster than normally we do, rather than we do an “Attach to Process” on the menu and search which w3wp, or even worse, by attaching it to all w3wp which we don’t need.

So, in the code below, I put 2 functions, AttachW3WP(string AppPoolName) and AttachProcess(string ProcessName). Same way, you can create another function, call that function to attach to particular w3wp process with specific Application Pool Name.

This should work with IIS 7.0 above, as IIS 6.0 (or even IIS 5.1) I’ve never tested it out.

Attach To Process
  1. Imports System
  2. Imports EnvDTE
  3. Imports EnvDTE80
  4. Imports EnvDTE90
  5. Imports EnvDTE90a
  6. Imports EnvDTE100
  7. Imports System.Diagnostics
  8. Imports System.Linq
  9. Imports System.ComponentModel
  10. Imports System.Collections
  11. Imports System.Collections.Generic
  12. Imports System.Management
  13.  
  14.  
  15. Public Module RdzMacros
  16.     Dim DebugPanel As String = "Debug"
  17.     Dim Ow As OutputWindow = DTE.ToolWindows.OutputWindow
  18.     Dim Owp As OutputWindowPane
  19.     Dim SetName As String = "ApplicationPoolName"
  20.     Dim Titl As String = "AttachW3WP"
  21.  
  22.  
  23.     Private Sub PanelInit()
  24.         Try
  25.             Owp = Ow.OutputWindowPanes(DebugPanel)
  26.         Catch ex As Exception
  27.             If Owp Is Nothing Then
  28.                 Owp = Ow.OutputWindowPanes.Add(DebugPanel)
  29.             End If
  30.         End Try
  31.     End Sub
  32.  
  33.     Private Function GetAppPoolName() As String
  34.         Dim sRet As String = ""
  35.         Try
  36.             sRet = DTE.Solution.Globals(SetName)
  37.         Catch ex As Exception
  38.         End Try
  39.         Return sRet
  40.     End Function
  41.  
  42.     Private Sub AttachW3WP(ByVal AppPoolName As String)
  43.         PanelInit()
  44.         Dim attached As Boolean = False
  45.         Dim proc As EnvDTE.Process
  46.         Dim ProcessName As String = "w3wp.exe"
  47.         Dim PID As Integer = 0
  48.         Dim CmdLine As String = AppPoolName 'GetAppPoolName()
  49.         If String.IsNullOrEmpty(CmdLine) Then
  50.             MsgBox("Set Application Pool Name first via 'SetApplicationPoolName' macro.", MsgBoxStyle.Critical, Titl)
  51.             Exit Sub
  52.         End If
  53.  
  54.         Owp.OutputString(String.Format("Search for IIS Worker Processes with AppPool '{0}'...", CmdLine))
  55.         Dim wmiQuery As String = "select CommandLine,ProcessID from Win32_Process where Name='" + ProcessName + "'"
  56.         Dim searcher As ManagementObjectSearcher = New ManagementObjectSearcher(wmiQuery)
  57.         Dim retObjectCollection As ManagementObjectCollection = searcher.Get
  58.         For Each retObject As ManagementObject In retObjectCollection
  59.             If retObject("CommandLine").ToString().ToLower().Contains("\" + CmdLine.ToLower() + "\") = True Then
  60.                 PID = Convert.ToInt32(retObject("ProcessID").ToString())
  61.                 Owp.OutputString(String.Format("Found the ProcessID: {0}...", PID.ToString))
  62.                 Exit For
  63.             End If
  64.         Next
  65.  
  66.         If PID > 0 Then
  67.             For Each proc In DTE.Debugger.LocalProcesses
  68.                 If proc.ProcessID = PID Then
  69.                     proc.Attach()
  70.                     attached = True
  71.                     Exit For
  72.                 End If
  73.             Next
  74.         End If
  75.         If Not attached Then
  76.             MsgBox("w3wp.exe with Argument '" + CmdLine + "' is not running!", MsgBoxStyle.Exclamation, "MiKrosok Pisual Studio 2010")
  77.         Else
  78.             Owp.OutputString(String.Format("ProcessID {0} already attached to VS debugger!", PID.ToString))
  79.             Owp.Activate()
  80.         End If
  81.     End Sub
  82.  
  83.     Private Sub AttachProcess(ByVal ProcessName As String)
  84.         PanelInit()
  85.         Dim attached As Boolean = False
  86.         Dim proc As EnvDTE.Process
  87.  
  88.         For Each proc In DTE.Debugger.LocalProcesses
  89.             If proc.Name.ToLower().Contains(ProcessName.ToLower()) Then
  90.                 proc.Attach()
  91.                 attached = True
  92.                 Exit For
  93.             End If
  94.         Next
  95.         If Not attached Then
  96.             MsgBox("'" + ProcessName + "' is not running!", MsgBoxStyle.Exclamation, "MiKrosok Pisual Studio 2010")
  97.         Else
  98.             Owp.OutputString(String.Format("ProcessName {0} already attached to VS debugger!", ProcessName))
  99.             Owp.Activate()
  100.         End If
  101.     End Sub
  102.  
  103.     Public Sub AttachOWSTimer()
  104.         AttachProcess("owstimer.exe")
  105.     End Sub
  106.  
  107.     Public Sub AttachOSCAR()
  108.         AttachW3WP("SharePoint - 80")
  109.     End Sub
  110.  
  111.     Public Sub AttachK2WorklistService()
  112.         AttachW3WP("K2WorklistService")
  113.     End Sub
  114.  
  115.     Public Sub AttachCommonWorkflowServices()
  116.         AttachW3WP("CommonWorkflowServices")
  117.     End Sub
  118.  
  119.     Public Sub AttachEIS()
  120.         AttachW3WP("SharePoint - 80 - EIS")
  121.     End Sub
  122. End Module

Hope it helps you.

16 Feb 2013

Backup-Restore Content of SharePoint 2010 Problems

So, I see a different issues coming up when we try to backup-restore content of SharePoint from one server to another. Most commonly issues that I found is that we will stuck on this message:

“Your backup is from a different version of Microsoft SharePoint Foundation and cannot be restored to a server running the current version. The backup file should be restored to a server with version '4.0.145.0' or later.”

Sometimes it says exact version like above, sometimes with another number of version. To resolve it, there’s more approach that Microsoft has provided.

There are 2 approaches to do a backup-restore of SharePoint content itself:

  1. SharePoint Site Collection backup.
  2. SharePoint Content Database backup.

First approach and always be the best approach (I’ve done this many times never fails):
Make sure both destination and source server have to be the exact same version, both in the SharePoint version or SharePoint build number.

With that approach, both solution can be applied. But of course, sometimes we happen to find a different version both on source or destination for some reason. Again, you could compare both versions, which one is higher. If the source is higher than destination, definitely you can’t just do a backup-restore the content straightaway. You need to make destination at least the same version as source. But if the source is lower than destination, on most cases it will just restored without problem.

But, if you notice my last sentence, that doesn’t mean totally without problem. Say you have SharePoint pre-SP1 as a source, and SharePoint with SP1 as a destination. This scenario can’t be done! But why?

That’s a logical question, because normally if the destination is higher version than source, it’ll do just straightaway, but this is not. The reason behind this is just as simple as this, pre-SP1 and SP1 content database structure has a big change and no backward compatibility.

How we are gonna do this? So, there are 2 approaches.

If you do a content-database backup as I said above, your approach will be easier as 1-2-3:

  1. Attach the pre-SP1 Content Database to an SP1 Farm. This can be done by adding the content database to the specific web application in SharePoint Central Administration.
  2. You have to run SharePoint Configuration Wizard to update the content database to SP1 version. Or if it’s failed, try run PSConfig command to upgrade it (PSConfig.exe -cmd upgrade -inplace b2b -force -cmd applicationcontent -install -cmd installfeatures).
  3. Detach the upgraded Content Database from that SP1 Farm. This can be done by removing the content database from specific web application in SharePoint Central Administration.
  4. Recover content as unattached database by running PowerShell command (Get-SPContentDatabase -ConnectAsUnattachedDatabase  -DatabaseName <DatabaseName> -DatabaseServer <DatabaseServer>).

But if you only “able” to get the site collection backup file from stsadm or PowerShell (because say some companies are restricting us to do a database backup or it has to go with some crazy procedures), here’s what you need to do (which is painful):

  1. Restore pre-SP1 site collection backup file to a new test pre-SP1 farm.
  2. Upgrade the test farm to SP1 until you finished running SharePoint Configuration Wizard.
  3. Perform a site collection backup from test farm.
  4. Perform a site collection restore to destination farm.

Any other way would be:

  1. Restore pre-SP1 site collection backup file to a new test pre-SP1 farm.
  2. Without upgrading, detach Content Database of test pre-SP1 farm.
  3. Attach pre-SP1 Content Database to an SP1 Farm.
  4. Upgrade it by using SharePoint Configuration Wizard or PSConfig as I mentioned above.
  5. Detach the upgraded Content Database.
  6. Recover content as unattached Content Database.

Hope it helps, guys…. Winking smile

 

reference: http://technet.microsoft.com/en-us/library/hh344831(v=office.14).aspx

6 Feb 2013

List of SharePoint Service Accounts

Hi guys,
Long time no blog since Aug 2012. Just want to share a little bit about SharePoint installation, List of SharePoint Service Accounts. These service accounts are grabbed from Microsoft Technet, and hope it useful for you.

Account Category Account Name Purpose Requirements
SQL Server Service Account SQL Server   The SQL Server service account is used to run SQL Server. It is the service account to run SQL Server service, MSSQLSERVER. > Domain user account.
SQL Server Setup User Account SQL Server   The Setup user account is used to run SQL Server Setup. > Domain user account.
> Member of the Administrators group on each SQL Server on which Setup is run.
SQL Server Agent Service Account SQL Server   The SQL Server service account is used to run SQL Server. It is the service account to run SQL Server Agent service, SQLSERVERAGENT. > Domain user account.
Application Pool Account SharePoint   The application pool account is used for application pool identity.
Recommended action is to make this account specific to each SharePoint Web Application.
> Domain user account.
> Registered Managed Accounts in Central Administration.
> This account must not be a member of the Farm Administrators group.
Content Access Account SharePoint   Content access accounts are configured to access content by using the Search administration crawl rules feature. This type of account is optional and you can configure it when you create a new crawl rule. For example, external content (such as a file share) might require this separate content access account. > Domain user account.
> The content access account must have read access to external or secure content sources that this account is configured to access.
> For SharePoint Server sites that are not part of the server farm, you have to explicitly grant this account full read permissions to the web applications that host the sites.
> This account must not be a member of the Farm Administrators group.
Default Content Access Account SharePoint   The default content access account is used within a specific service application to crawl content, unless a different authentication method is specified by a crawl rule for a URL or URL pattern. > Domain user account.
> The content access account must have read access to external or secure content sources that this account is configured to access.
> For SharePoint Server sites that are not part of the server farm, you have to explicitly grant this account full read permissions to the web applications that host the sites.
> This account must not be a member of the Farm Administrators group.
Excel Services Unattended Service Account SharePoint   Excel Services uses the Excel Services unattended service account to connect to external data sources that require a user name and password that are based on operating systems other than Windows for authentication. If this account is not configured, Excel Services will not attempt to connect to these types of data sources. Although account credentials are used to connect to data sources of operating systems other than Windows, if the account is not a member of the domain, Excel Services cannot access them. > Domain user account.
My Sites Application Pool Account SharePoint   The application pool account is used for My Site application pool identity.
Recommended action is to make this account specific to each SharePoint Web Application.
> Domain user account.
> Registered Managed Accounts in Central Administration.
> This account must not be a member of the Farm Administrators group.
Server farm account or database access account SharePoint   The server farm account is used to perform the following tasks: Configure and manage the server farm, act as the application pool identity for the SharePoint Central Administration Web site, run the Microsoft SharePoint Foundation Workflow Timer Service. > Domain user account.
> Additional permissions are automatically granted for the server farm account on Web servers and application servers that are joined to a server farm.
> The server farm account is automatically added as a SQL Server login on the computer that runs SQL Server. The account is added to the following SQL Server security roles: 'dbcreator' fixed server role, 'securityadmin' fixed server role, 'db_owner' fixed database role for all SharePoint databases in the server farm.
Service Application Application Pool Account SharePoint   The application pool account is used for service application application pool identity.
Recommended action is to make this account to be used in all SharePoint Service Application across farm.
> Domain user account.
> Registered Managed Accounts in Central Administration.
SharePoint Setup User Account SharePoint   The Setup user account is used to run the following, SharePoint Setup and SharePoint Products Configuration Wizard. > Domain user account.
> Member of the Administrators group on each SharePoint server on which Setup is run.
> SQL Server login on the computer that runs SQL Server.
> Member of the following SQL Server roles: 'securityadmin' fixed server role and 'dbcreator' fixed server role.
SharePoint User Profile Service Account SharePoint   The user account is used to run the User Profile Synchronization service. Configured under User Profile Service Application for a connection to Active Directory. > Domain user account.
> Registered Managed Accounts in Central Administration.
> Replicating Directory Changes rights in Active Directory security management.
SharePoint Search Service Account SharePoint   The user account is used to run the Search Service Application. > Domain user account.
> Registered Managed Accounts in Central Administration.


Maybe you wonder why we must separate service account to several accounts. The exact reason behind is, I don't know. But from what I have heard from Microsoft's employee when I was doing some troubleshooting, is that easier for them to do debugging if something goes wrong. SharePoint is the most crazy product that I've ever know! Integrating with so many softwares and services such as FAST Search, Performance Point, Forefront Identity Manager, and any type of Directories (Active Directory). Any type of users they trying to grab and make love with them. And now what they're trying to do is to make love with "many type" of developers. And, maybe we don't know exactly which one causing error, but they do know. So, doing this thing is quite important at the time they need it. Trust me, its hard to track while debugging some code issue without isolating the case!