Create User or Assign Company Access Without Using sa

Microsoft Dynamics GPWith Microsoft Dynamics GP, there are only two user accounts which can, by default, create new users or assign access to companies; these the the sa (SQL Server System Administrator) and DYNSA (Dynamics GP System Administrator).

The former account should only be used when absolutely necessary (such as when implementing Microsoft Dynamics GP or moving it to a new SQL Server Instance; there are some ISV products which also insist on the sa account when it isn’t strictly necessary from a tecHnical perspective).

The recommended way of maintaining security is to configure a normal user account with the permissions necessary to create and assign users to companies. There are a few steps to go through to assign the relevant security.

Mark Polino did a post a while ago on adding users without using the sa account, but, in this post, Mark assigned the sysadmin role to the user. While this will do the job, and in fewer steps, I prefer to lock down security so users only have the permissions required, which precludes assigning a sysadmin role. The reason for this is both best practice, but also that I have several clients who will not allow the sysadmin role to be assigned to a GP user.

The following steps cover the minimum security required for a user to be able to add new users or assign them access to companies.

Assign the user to all companies in Microsoft Dynamics GP (this is done in the User Access Setup window (Administration area page » Setup » System » User Access):

User Access Setup

Continue reading “Create User or Assign Company Access Without Using sa”

Formatting SQL

Microsoft SQL ServerI create a fair amount of T-SQL in the form of selects, views and stored procedures. While I try to format my code to make it easy to use, I do encounter code from other people which is not very well formatted; and if you look at the stored procedures or views which ship with Microsoft Dynamics GP, they are generally formatted with all of the code on a single line.

There are a variety of ways of formatting SQL and I’m sure there are addins for SQL Server Management Studio; however, I often work on clients servers and can’t just install anything I want.

Therefore, a web based alternative is favourite and SQLFormat is the best one I have come across so far.

To use, simple paste your code into the big box and click the Format SQL button:

SQLFormat

You can even load a file should you wish.

I’m posting it here as a reminder to myself.

Implementing SmartConnect: System Requirements

eOne SolutionsThis post is part of the series on Implementing SmartConnect, an integration tool from eOne Solutions, which can take data from any source and integrate it into Microsoft Dynamics GP (and other systems such as Microsoft Dynamics CRM or Sales Force amongst others). It has a drag and drop interface to make creating integrations quick and easy for all users rather than just developers (as many integration tools target).

Before starting to install SmartConnect, the following requirements should be checked to ensure compatibility; if procureing new servers or software, I’d generally advise to aim for the top of the requirements to ensure greatest longevity.

Processors:

  • 32 bit processor machines, 2 GHz or greater.
  • 64 bit processor machines, 2 GHz or greater.

Memory (RAM):

  • 1 GB of RAM is required, at least 4GB is recommended.

Continue reading “Implementing SmartConnect: System Requirements”

How to Install Microsoft SQL Server 2017: Download SSRS 2017

Microsoft SQL ServerIn this short series of posts, I am going to be covering the installation of Microsoft SQL Server 2017; the installation process for this version is somewhat different to previous ones, in that SQL Server Management Studio and SQL Server Reporting Services have been separated out from the main installer.

The series index can be found here. I am not a SQL expert and this series of posts is intended only for use on demo or test environment and not production ones.

This is a very late addition to this series of posts; I recently came to install SQL Server 2017 on a new machine which did not have an Internet connection and so needed to download the installer and copy itto the new machine.

In the installation post I used the download option in the installer, but didn’t include the direct download link.

Well, to remedy that, here is the download link to the latest version of SSRS 2017.

SQL Snippet: Get Dates for Accruals

Microsoft SQL ServerAs I’ve mentioned before I write a fair bit of SQL code for various projects or support calls and will be posting some of it here.

I recently created a report for a client to use to extract transaction lines to use to import as an accruals journal; as part of the extract I worked out the last day of the one month and the first day of the next to use as the transaction and reversing dates on the journal.

The scripts below has versions for both before and after SQL 2012 (with the introduction of the EOMONTH function in 2012, getting these dates became easier).

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
-- set date variable
DECLARE @Date DATETIME = GETDATE()

-- get last date of this month
SELECT CONVERT(VARCHAR(10), DATEADD(month, ((YEAR(@Date) - 1900) * 12) + month(@Date), -1), 126)

-- get last date of this month in SQL 2012
SELECT EOMONTH(@Date)

-- get first date of next month
SELECT CONVERT(VARCHAR(10), DATEADD(month, DATEDIFF(month, 1, DATEADD( month, 1, @Date )), 0), 126)

-- get first date of next month in SQL 2012
SELECT DATEADD(day, 1, EOMONTH(@Date))

SQL Collation – SQL_Latin1_General_CP1_CI_AS vs Latin1_General_CI_AS by Craig Verster via WinthropDC

Microsoft Dynamics GPOver the last few years as we have grown the ERP Practice at Perfect Image we have taken over a number of clients from other Microsoft Dynamics GP partners, both in the UK and elsewhere. Far too many of them have had Dynamics GP installed with the incorrect collation.

According to the system requirements, Microsoft Dynamics GP is supported with two collations:

  • SQL_Latin1_General_CP1_CI_AS (the recommend one as it is case insensitive).
  • Latin1_General_BIN

Whenever I install SQL Server, I am careful to ensure that I pick the SQL_Latin1_General_CP1_CI_AS collation which is supported; this is important to do, as a UK language server has Latin1_General_CI_AS as the default and you need to proactively make the change. A US server has the correct collation by default.

If I’m honest, I couldn’t have told you why this was important, but it is something I have always been very careful to do. I couldn’t have told you why this was important, until today that is, when I read a guest post by Craig Verster, Senior Microsoft Dynamics GP Consultant at Microchannel Services, on the a href=’https://winthropdc.wordpress.com/’>Winthrop DC blog.

The post by Craig explains why it is important to use the correct collation. Short version is that while both SQL_Latin1_General_CP1_CI_AS and Latin1_General_CI_AS are 1252 character collations, they handle the Þ character different which can cause incorrect data to be returned in the Reporting Service Reports; there could also be other places where this manifests.

I’d encourage everyone (especially consultants) to read and understand the post so we can stop clients having an incorrect collation installed on the SQL Server used with Microsoft Dynamics GP.

New GP Compatibility Page Available

Microsoft Dynamics GPI’ve added a GP Resources section to this site; as well as links to the GP Table Reference, I’ve created a Microsoft Dynamics GP Compatibility page which shows the compatibility with SQL Server, Windows Server and Windows from Dynamics GP 2010 through to 2018.

If you see any errors, or can contribute information on supported versions, prior to 2010, please contact me with the information.

SQL Script to Change Compatibility of All Databases

Microsoft Dynamics GPWhen moving databases between servers for an upgrade of Microsoft Dynamics GP, you will, when also upgrading SQL Server, need to change the compatibility level of the databases. Rather than dong this individually, the below script can be run against the system database to generate a script you can then run to update the compatibility level of all databases.

The highlighted variable should be changed to the relevant version.

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
DECLARE @CompatibilityLevel VARCHAR(140) = 140


SELECT 'USE master
	GO
	ALTER DATABASE [' + DB_NAME() + '] SET COMPATIBILITY_LEVEL = ' + @CompatibilityLevel + '
	GO'
UNION ALL
	SELECT '
		ALTER DATABASE [' + ['Company Master'].INTERID + '] SET COMPATIBILITY_LEVEL = ' + @CompatibilityLevel + '
		GO'
	FROM
		SY01500 AS ['Company Master']
GO

This script doesn’t get the logical file name, but I’ve hooked it into the series I did on Logical File Name SQL Scripts as it will often be needed at the same time.

SQL Script to Change Database Owner of All Databases

Microsoft Dynamics GPWhen moving databases between servers, you need to make sure the databases are set to have an owner of DYNSA. Rather than dong this individually, the below script can be run against the system database to generate a script you can then run to update the db owner.

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
SELECT 'USE [' + DB_NAME() + ']
	GO
	sp_changedbowner ''DYNSA''
	GO'
UNION
	SELECT 'USE [' + ['Company Master'].INTERID + ']
		GO
		sp_changedbowner ''DYNSA''
		GO'
	FROM
		SY01500 AS ['Company Master']
GO

This script doesn’t get the logical file name, but I’ve hooked it into the series I did on Logical File Name SQL Scripts as it will often be needed at the same time.

Logical File Name SQL Scripts: SQL Script to Create Restore Scripts for all Dynamics Databases

Microsoft SQL ServerSince the release of Microsoft Dynamics GP 2018, on the 1st December 2018, we have been busy with a few upgrade projects for clients. Our standard recommendation is to have a standalone test system for performing UAT and this means backing up and restoring databases.

While the backups are easy to do, the restores can be trickier when one database has been restored into another, as this means the logical file name will not match the physical one.

This isn’t an issue when the client has only a handful of databases, but when there are 30 or even a hundred, it becomes much more of an issue. However, you can select database details in SQL Server from the sys.master_files single, system-wide view.

This script creates restore scripts for all Dynamics GP databases and will use the correct logical filename whether it matches the . The script is configured with the assumption that the system database is called DYNAMICS; if you are using a named system database, change the highlighted section:

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
USE DYNAMICS
GO

DECLARE @BackupLocation VARCHAR(300) = 'I:\Live Upgrade\2016R2\'
DECLARE @DataLocation VARCHAR(300) = 'S:\Data\'
DECLARE @LogLocation VARCHAR(300) = 'L:\Logs\'
DECLARE @DateParameter VARCHAR(10) = FORMAT(GETDATE(), 'yyyy-MM-dd')
DECLARE @SQLStatement NVARCHAR(MAX)
SELECT @SQLStatement =	'
	USE master
	GO
	RESTORE DATABASE ' + DB_NAME() + ' FROM  
	DISK = N''' + @BackupLocation + DB_NAME() + '_' + @DateParameter + '.bak'' WITH  FILE = 1,  
	MOVE N''' + ['databases-data'].name + ''' TO N''' + @DataLocation + RIGHT(['databases-data'].physical_name, CHARINDEX('\', REVERSE(['databases-data'].physical_name)) - 1) + ''',  
	MOVE N''' + ['databases-log'].name + ''' TO N''' + @LogLocation + RIGHT(['databases-log'].physical_name, CHARINDEX('\', REVERSE(['databases-log'].physical_name)) - 1) + ''',  NOUNLOAD,  STATS = 5
	GO
	'
FROM
	sys.master_files AS ['databases-data']
INNER JOIN
	sys.master_files AS ['databases-log']
		ON
			DB_NAME(['databases-log'].database_id) = DB_NAME(['databases-data'].database_id)
WHERE
	DB_NAME(['databases-data'].database_id) = DB_NAME() and ['databases-data'].name like '%.mdf'

SELECT @SQLStatement = @SQLStatement + 
	'RESTORE DATABASE ' + RTRIM(['Company Master'].INTERID) + ' FROM  
	DISK = N''' + @BackupLocation + RTRIM(['Company Master'].INTERID) + '_' + @DateParameter + '.bak'' WITH  FILE = 1,  
	MOVE N''' + ['databases-data'].name + ''' TO N''' + @DataLocation + RIGHT(['databases-data'].physical_name, CHARINDEX('\', REVERSE(['databases-data'].physical_name)) - 1) + ''',  
	MOVE N''' + ['databases-log'].name + ''' TO N''' + @LogLocation + RIGHT(['databases-log'].physical_name, CHARINDEX('\', REVERSE(['databases-log'].physical_name)) - 1) + ''',  NOUNLOAD,  STATS = 5
	GO
	'
FROM
	SY01500 AS ['Company Master']
INNER JOIN
	sys.master_files AS ['databases-data']
		ON
			DB_NAME(['databases-data'].database_id) = ['Company Master'].INTERID AND ['databases-data'].name LIKE '%mdf'
INNER JOIN
	sys.master_files AS ['databases-log']
		ON
			DB_NAME(['databases-log'].database_id) = ['Company Master'].INTERID AND ['databases-log'].name LIKE '%ldf'
WHERE
	['databases-data'].name NOT LIKE '%<TEST>'
AND
	['Company Master'].CMPANYID > 0
ORDER BY
	['Company Master'].INTERID
	,['databases-data'].name

SELECT @SQLStatement