Move SQL databases between two servers
Had to look into moving all SharePoint Databases to a new SQL Server (2012 of course). Used the backup script I previously posted and found a restore script:
I used the 2008 to 2012 restore script but edited it slightly:
/********************************************************************************
* Restore SQL server 2008 backed databases to
* SQL server 2012
********************************************************************************/
use master;
go
/* Please un-comment below part to enable cp_cmdshell procedures
Don't forget to disable it after migration completed.
EXEC sp_configure'xp_cmdshell', 1
RECONFIGURE
GO
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
GO*/
DECLARE @Return int
IF OBJECT_ID('tempdb..#SQL2008BackedUpdatabases') IS NOT NULL DROP TABLE #SQL2008BackedUpdatabases
CREATE TABLE #SQL2008BackedUpdatabases (BakFileName varchar(400), ID int IDENTITY(1,1))
INSERT #SQL2008BackedUpdatabases EXECUTE @Return = master.dbo.xp_cmdshell 'dir /B *.bak D:\SharePoint'
DECLARE UserDatabases_CTE_Cursor Cursor
FOR
-- Restoring user database names.
select BakFileName from #SQL2008BackedUpdatabases
where BakFileName like '%bak'
OPEN UserDatabases_CTE_Cursor
DECLARE @BakFileName varchar(200);
DECLARE @dbName varchar(200);
DECLARE @backupPath varchar(200);
DECLARE @SQL2012RestoreFolder varchar(200);
DECLARE @backupQuery varchar(600);
-- make sure that the below path exists
set @backupPath = 'D:\SharePoint\'
-- make sure that the below path exists
set @SQL2012RestoreFolder = 'G:\MSSQL11.SQLSHAREPOINT\MSSQL\DATA\'
set @SQL2012RestoreFolder = 'G:\MSSQL11.SQLSHAREPOINT\MSSQL\DATA\'
Fetch NEXT FROM UserDatabases_CTE_Cursor INTO @BakFileName
While (@@FETCH_STATUS <> -1)
BEGIN
set @dbName = REPLACE(@BakFileName, '.bak', '')
-- Restore SQL 2008 backed databases to SQL server 2012
set @backupQuery = 'RESTORE DATABASE [' +@dbName
+ '] FROM DISK = ''' + @backupPath + @BakFileName +''' '
+'WITH MOVE ''' + @dbName +''' TO ''' + @SQL2012RestoreFolder + @dbName + '.mdf'','
+ 'MOVE ''' + @dbName +'_Log'' TO ''' + @SQL2012RestoreFolder + @dbName +'.ldf'''
-- Print SQL statement
print @backupQuery
-- Execute backup script
EXEC (@backupQuery)
-- Get next database
Fetch NEXT FROM UserDatabases_CTE_Cursor INTO @BakFileName
END
CLOSE UserDatabases_CTE_Cursor
DEALLOCATE UserDatabases_CTE_Cursor
GO
If you want to simply create the restore commands without actually restoring you can comment out the EXEC line at the end. Also make sure to adjust the parts marked in red to your needs.
Thanks,
Andreas
Office applications requesting Authentication for SharePoint
Had a problem recently with SharePoint 2010 when we changed our main way of accessing the site to a public domain name. This change made all Office Applications 2007 and 2010 request authentication when opening and saving to or from SharePoint.
After a longer research into the issue I found this Microsoft KB.
In there Microsoft informs about how WebDav secures sites or networks. I always knew that SharePoint uses WebDav to share documents to Office applications however I had no idea that you had to specify a trusted location if it uses an Internet FQDN instead of a local netbios name.
So I followed the KB and I actually deloyed the registry key via Group Policy Prefferences and after people restarted their PCs no more calls about having to authenticate.
Thanks,
Andreas
Transfer logins between SQL instances
I just moved our SharePoint 2010 and Project 2010 databases (Yeah it uses like 10). Anyway I realized that moving the database and creating the SQL Alias, so the server believes that the Database is still local, is going to be easy. However I also wanted the same logins on the new remote instance as I had on the local instance. After a quick google I found a script from Microsoft support: http://support.microsoft.com/kb/918992/
First run this Query:
USE master
GO
IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL
DROP PROCEDURE sp_hexadecimal
GO
CREATE PROCEDURE sp_hexadecimal
@binvalue varbinary(256),
@hexvalue varchar (514) OUTPUT
AS
DECLARE @charvalue varchar (514)
DECLARE @i int
DECLARE @length int
DECLARE @hexstring char(16)
SELECT @charvalue = '0x'
SELECT @i = 1
SELECT @length = DATALENGTH (@binvalue)
SELECT @hexstring = '0123456789ABCDEF'
WHILE (@i <= @length)
BEGIN
DECLARE @tempint int
DECLARE @firstint int
DECLARE @secondint int
SELECT @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1))
SELECT @firstint = FLOOR(@tempint/16)
SELECT @secondint = @tempint - (@firstint*16)
SELECT @charvalue = @charvalue +
SUBSTRING(@hexstring, @firstint+1, 1) +
SUBSTRING(@hexstring, @secondint+1, 1)
SELECT @i = @i + 1
ENDSELECT @hexvalue = @charvalue
GOIF OBJECT_ID ('sp_help_revlogin') IS NOT NULL
DROP PROCEDURE sp_help_revlogin
GO
CREATE PROCEDURE sp_help_revlogin @login_name sysname = NULL AS
DECLARE @name sysname
DECLARE @type varchar (1)
DECLARE @hasaccess int
DECLARE @denylogin int
DECLARE @is_disabled int
DECLARE @PWD_varbinary varbinary (256)
DECLARE @PWD_string varchar (514)
DECLARE @SID_varbinary varbinary (85)
DECLARE @SID_string varchar (514)
DECLARE @tmpstr varchar (1024)
DECLARE @is_policy_checked varchar (3)
DECLARE @is_expiration_checked varchar (3)DECLARE @defaultdb sysname
IF (@login_name IS NULL)
DECLARE login_curs CURSOR FORSELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
sys.server_principals p LEFT JOIN sys.syslogins l
ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name <> 'sa'
ELSE
DECLARE login_curs CURSOR FORSELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
sys.server_principals p LEFT JOIN sys.syslogins l
ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name = @login_name
OPEN login_cursFETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
IF (@@fetch_status = -1)
BEGIN
PRINT 'No login(s) found.'
CLOSE login_curs
DEALLOCATE login_curs
RETURN -1
END
SET @tmpstr = '/* sp_help_revlogin script '
PRINT @tmpstr
SET @tmpstr = '** Generated ' + CONVERT (varchar, GETDATE()) + ' on ' + @@SERVERNAME + ' */'
PRINT @tmpstr
PRINT ''
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
PRINT ''
SET @tmpstr = '-- Login: ' + @name
PRINT @tmpstr
IF (@type IN ( 'G', 'U'))
BEGIN -- NT authenticated account/groupSET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' FROM WINDOWS WITH DEFAULT_DATABASE = [' + @defaultdb + ']'
END
ELSE BEGIN -- SQL Server authentication
-- obtain password and sid
SET @PWD_varbinary = CAST( LOGINPROPERTY( @name, 'PasswordHash' ) AS varbinary (256) )
EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUT
EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT-- obtain password policy state
SELECT @is_policy_checked = CASE is_policy_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name
SELECT @is_expiration_checked = CASE is_expiration_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @nameSET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' WITH PASSWORD = ' + @PWD_string + ' HASHED, SID = ' + @SID_string + ', DEFAULT_DATABASE = [' + @defaultdb + ']'
IF ( @is_policy_checked IS NOT NULL )
BEGIN
SET @tmpstr = @tmpstr + ', CHECK_POLICY = ' + @is_policy_checked
END
IF ( @is_expiration_checked IS NOT NULL )
BEGIN
SET @tmpstr = @tmpstr + ', CHECK_EXPIRATION = ' + @is_expiration_checked
END
END
IF (@denylogin = 1)
BEGIN -- login is denied access
SET @tmpstr = @tmpstr + '; DENY CONNECT SQL TO ' + QUOTENAME( @name )
END
ELSE IF (@hasaccess = 0)
BEGIN -- login exists but does not have access
SET @tmpstr = @tmpstr + '; REVOKE CONNECT SQL TO ' + QUOTENAME( @name )
END
IF (@is_disabled = 1)
BEGIN -- login is disabled
SET @tmpstr = @tmpstr + '; ALTER LOGIN ' + QUOTENAME( @name ) + ' DISABLE'
END
PRINT @tmpstr
ENDFETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
END
CLOSE login_curs
DEALLOCATE login_curs
RETURN 0
GO
This creates two stored procedures in the master database.
To actually use the stored procedure to create a script for us you need to be logged in with a user that has the SQL server sysadmin role.
If you have that role go ahead and run:
EXEC sp_help_revlogin
as a new Query.
The result of the query should be a SQL query script that creates the logins on the new server. Before I ran it on the new server I deleted all the logins that already exist for example my own, local system and etc.
Now you only have to be sysadmin on the new SQL instance so you can run the script on there and you should be all set.
I hope it works for you as good as it did for me
Andreas
2 Server Redundant Exchange 2010 configuration
I have been working on Exchange 2010 especially doing a redundant configuration with using the least amount of systems because I am working with a very small environment and I only want good data and access redundancy.
Anyway I found these three articles that really cleared things up:
In these three articles they cover everything you will need to know about load balancing the two servers. It is quite simple actually. Install all roles on both servers. Now you will have to edit the registry to not use a dynamic port for RPC which is used by IMAP and Directory Access:
On the CAS servers, for Mailbox connections, you need to use add a DWORD registry key named “TCP/IP Port” under: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSExchangeRpc\ParametersSystem
Figure 8: Adding the required DWORD key on CAS server to configure a static port numberSet the value to the port number to be assigned. In this article we use port 55000, but you are free to choose whatever port you want to use, just remember it should not conflict with other applications using the port. It is recommend you choose a port within the dynamic RPC ranger (1024-65535).
This is from Part 2.
If you set this on both the servers you will need a lot less ports to load balance then before. I am basing this on Kentrox LoadMasters. They are a great product but the only thing they are missing right now is load balancing port ranges. This of course is no big deal after using the registry edit to change it from a dynamic port range to a single static port.
If you have different load balancers you might be able to just load balance the entire servers but it doesn’t matter if you do or not.
Also very good information is in Part 1 about Persistence and in Part 3 about the exact settings of the Kentrox Load Masters.
I also discovered a great website from Microsoft which can help you test outside Exchange connectivity. I know it supports Exchange 2010 but it might work for 2007 as well. Even if the site is made my Microsoft I would for sure not use an account that is actually going to be used with this site. Anyway here is the site and it pretty much tests anything you could.
https://www.testexchangeconnectivity.com/
I hope you have fun,
Andreas
HP LaserJet 1022 issues
Recently I was trying to fix an issue with an HP LaserJet 1022 on a Windows 7 x86 machine with an USB connection. The issue was that if certain files were being printed it would kill the print spooler until you clean it out (delete the print spooler files manually). I found that the biggest problem files were PDF files.
So I stated researching and found the following post:
http://arstechnica.com/civis/viewtopic.php?f=11&t=327353
In this post they are describing a very similar issue. They are also talking about that the solution is using a PCL driver (which by the product description it natively supports). However HP is unique in this case. They don’t actually have a PCL driver for this printer they only have a Host Based printer driver.
They requested help from HP who actually told them to use a HP LaserJet 6L driver.
|
Dear HP Customer, |
So by this answer from HP we can see that they are obviously aware of the problem but decided not to fix it and give a work around instead.
It works perfectly fine to use the LaserJet 6L driver. If you can’t see the driver when installing the printer you can press Windows Update in Windows 7 and Vista in order for it download a lot of drivers from Windows Update.
I hope this helps somebody
Andreas
Find out what caused a BSOD
Of course you can use good old Google and find out what the BSOD stands for but this only gets you so far. (my favorite site with most BSODs on it is this one: http://www.aumha.org/a/stop.php)
If you want more and your computer has its pagefile on the C drive it will try to create a Crash dump Memory file under C:\Windows called Memory.dmp
This file you can analyze. I followed this instructions:
http://www.brighthub.com/computing/windows-platform/articles/29860.aspx
However you can simplfy this:
Go to this page: http://www.microsoft.com/downloads/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b&displaylang=en
Download the utility and run it. It will automatically detect the right version and guide you through the install.
On this screen only select the Common Utilities (I installed the Redistributable packages as well just to make sure everything works)
After it downloads and installs everything go into your start menu and open up WinDbg. Now click on File - Symbol File path and paste the following into the window:
SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
and click ok.
Now just open the crash dump .dmp file with file - open crash dump. Once analyzed it will let you know what file it thinks the problem file was.
( I in the past had a lot of luck when there were corrupt or buggy drivers on the system) If you end up with a .sys file you can usually Google it to find out what driver it is.
When it is down with analyzing you can click on the links in blue to get more inept (hint the "!analyze -v" is very helpful)
I hope that helps somebody with a BSOD problem
Andreas
UPDATE:
Correction from before: The only thing required to run the debugging tools is the actual debugging tools under Common Utilities. Also the .net 4.0 is not required.
SQL SPNs can really bite you in the you know what
I was moving some databases from local SQL servers to one remote SQL server. The new Remote box is a SQL 2008 R2 box and I do have to say I like SQL 2008 and R2 a lot. Anyway I was moving a SCCM 2007 R2 SP2 Site database and the VMM 2008 R2 database to this server and nothing was quite working right. It for some reason was trying to authenticate with NT Anonymous logon which I of course didn't wnat to open up my database to everybody and their brother. So i researched a bit and found this article:
http://poseidom.wordpress.com/2007/12/16/set-spn-for-sql-2005-sccm-remote-sql-fix/
I know it is for SQL 2005 however it works on SQL 2008 and R2 just as well and I would actually say you should do that with every SQL server, that uses a domain service account, you got because sooner or later you will run into that problem.
I actually did the Method 2 on his blog because i might want some more instances and i don't want to worry about SPNs any more! (also for teh 2nd Method you don't need the port numbers)
Method 1: The “Right” way
- Install the Windows 2003 support tools somewhere on a machine in the domain
- Login as a Domain Admin
- Run setspn -A MSSQLSvc/<FQDN> <SQL_Service_Account> Note YOU MUST USE THE FQDN
- Run setspn -A MSSQLSvc/<FQDN>:<Port> <SQL_Service_Account> Note YOU MUST USE THE FQDN, and the most common port is 1443
- Run setspn -L <SQL_Service_Account> validate that “servicePrincipalName:” has been set like you expect
- Restart the SQL server after AD replication has completed
- Run the following query on the SQL server; this MUST return KERBEROS:
select auth_scheme from sys.dm_exec_connections where session_id=@@spid
Method 2: The “easy” way
In adsiedit grant the service account the ability to write the servicePrincipalName to “SELF”
Taken from: http://support.microsoft.com/kb/319723
-
- Click Start, click Run, type Adsiedit.msc, and then click OK.
- Note The ADSIEdit tool is included in the Windows Support Tools. To obtain the Windows Support Tools, visit the following Microsoft Web site: http://www.microsoft.com/downloads/details.aspx?familyid=6EC50B78-8BE1-4E81-B3BE-4E7AC4F0912D&displaylang=en
- In the ADSI Edit snap-in, expand Domain [DomainName], expand DC= RootDomainName, expand CN=Users, right-click CN= AccountName , and then click Properties.
- DomainName is a placeholder for the name of the domain.
- RootDomainName is a placeholder for the name of the root domain.
- AccountName is a placeholder for the account that you specify to start the SQL Server service.
- If you specify the Local System account to start the SQL Server service, AccountName is a placeholder for the account that you use to log on to Microsoft Windows.
- If you specify a domain user account to start the SQL Server service, AccountName is a placeholder for the domain user account.
- In the CN= AccountName Properties dialog box, click the Security tab.
- On the Security tab, click Advanced.
- In the Advanced Security Settings dialog box, make sure that SELF is listed under Permission entries.
- If SELF is not listed, click Add, and then add SELF.
- Under Permission entries, click SELF, and then click Edit.
- In the Permission Entry dialog box, click the Properties tab.
- On the Properties tab, click This object only in the Apply onto list, and then click to select the check boxes for the following permissions under Permissions:
- Read servicePrincipalName
- Write servicePrincipalName
- Click OK two times.
- Click Start, click Run, type Adsiedit.msc, and then click OK.
Of course the first method is more secure and probably better for most environments but if your environment is like mine where stuff changes every week I would go with Method 2.
Anyway now both SCCM and VMM are happy like never before. They like not having a SQL server on the same box.
Andreas
Backup all SQL Databases in one instance
So today I was going to move a hole bunch of SQL databases from one server to another. All DBs are used very seldom so no issue about people connecting and stuff. However I was looking at those databases and I didn't want to click through the backup wizard like 20 times and I didn't want to execute a backup command that often either. So i went for a quick search and found the following stored procedure from this site: http://www.kodyaz.com/articles/sql-server-backup-script-for-all-databases.aspx
This is the script:
CREATE PROC BackupDatabase (
@DatabaseName sysname ,
@SQLBackupFolder nvarchar(400)
)
AS
DECLARE @BackupSQLScript nvarchar(max)
DECLARE @SQLBackupFileName nvarchar(400)
SET @SQLBackupFileName =
REPLACE(@DatabaseName,' ','-') +
CONVERT(VARCHAR,GETDATE(),112) + '.bak'
SET @BackupSQLScript = '
BACKUP DATABASE [' + @DatabaseName + ']
TO DISK = ''' + @SQLBackupFolder + @SQLBackupFileName + ''''
print @BackupSQLScript
EXEC sp_executesql @BackupSQLScript
GO
I simply edited that it inserts a dash between DB name and date for the file name:
CREATE PROC BackupDatabase (
@DatabaseName sysname ,
@SQLBackupFolder nvarchar(400)
)
AS
DECLARE @BackupSQLScript nvarchar(max)
DECLARE @SQLBackupFileName nvarchar(400)
SET @SQLBackupFileName =
REPLACE(@DatabaseName,' ','-') + (' - ') +
CONVERT(VARCHAR,GETDATE(),112) + '.bak'
SET @BackupSQLScript = '
BACKUP DATABASE [' + @DatabaseName + ']
TO DISK = ''' + @SQLBackupFolder + @SQLBackupFileName + ''''
print @BackupSQLScript
EXEC sp_executesql @BackupSQLScript
GO
After running this you have the stored procedure in your instance and therefore you will be able to run the actual backup script:
EXEC sp_Msforeachdb "
DECLARE @BackupFolder nvarchar(400);
SELECT @BackupFolder = 'C:\backups\';
EXEC BackupDatabase '?', @BackupFolder
"
Oh yeah don't forget to replace C:\backups\ with the folder you want to backup to. (and also don't forget the backslash at the end!!)
Oh and almost forgot if you don't know how to backup just one DB through the Management studio here is a link from that same site:
http://www.kodyaz.com/articles/sql-backup-sql-server-backup-database.aspx
And have fun backing up or moving DBs
Andreas
Silently deploy Adobe CS5 (or CS4)
Just the other day my company bought a few volume licenses for Adobe Illustrator CS5. So I thought hey lets do a silent deployment through SCCM.
After looking up some things on google I came across the Adobe Developer Connection site where I found a nice little toolkit that can create silent installs:
http://www.adobe.com/devnet/creativesuite/enterprisedeployment.html
By the way there is one for the CS4 version as well and if your company doesn't have a volume key you can still customize the install and have it ask for a serial.
Have fun,
Andreas
Customize OSD deployments in SCCM
OSD in SCCM is great and can be customized very easily.
I first ran across a great HTA script written by Nick Mosely. With this script you are able to add in a selection for different applications. I then edited the script to suit my needs:
This script will only run properly inside the OSD PXE environment (it might run inside OSD before the restart as well but I didn't test that)
My script sets a bunch of OSD variables that then install the applications. In order to set the computer name and if needed add a user to the Administrators group I use:
With this little tool you can use regex to check and make sure that the computer name follows the corporate standards (if any).
Recently I have also discovered a nice little program that might soon replace the HTA script because it just looks so much better:
With this program the really cool thing is that you can create application sets in order to force applications for certain sites. You can also enforce certain applications but leave others open for selection/deselection.
If I actually have some time I might end up redoing my script inside the OSDAppChooser. We will see.
And actually before I forget about it. Here is my script to add a user to the local Admin group. I kind of added the script together from several different places and added my own touches to it. It might not be pretty but it works. This script has to be run during the last part of the OSD setup phase (when it installs the software as well) I first grab the user name from the OSD variable Local_Admin then I add it to that admin group:
Later,
Andreas
Group Policy to Hide any Drive(letter)
Today I ran into a little snag. After installing App-v 4.6 Agent I ran into the issue that the P: drive was showing up on my machine, which of course bothered me because that would be unacceptable on a client machine.
I researched around a bit and found a great solution with which you can hide any set of drive letters you want:
I first took the registry key to hide drive letters from this website:
http://www.winvistatips.com/hide-hard-drive-t133674.html
I then used the reg-to-admx/adml converter from:
http://gallery.technet.microsoft.com/ScriptCenter/en-us/8c703a2e-4685-4093-a1fc-dec107c53d13
I then further edited the admx and adml file to for example actually accept the large numbers and also to make it look pretty. Here you can download the admx template that I ended up with:
http://blog.andreasfelder.com/shared/Hide-drive.zip
To install the template drop the unpacked version into your PolicyDefinitions folder under:
\\"DC-NAME"\SYSVOL\"DOMAIN-NAME"\Policies\PolicyDefinitions
Have fun with hiding any drives you want and I will never know why Micorosft didn't include more options in their default policy.
Later,
Andreas


