CRM 2016 – Administration

  1.  CRM 2016 – Online vs on-premises features FAQ

2.  Online vs on-premises features ( in the list)

3. Microsoft Dynamics CRM Help & Training 

4. CRM Installation Guide – The Ultimate Dynamics CRM Installer (AgileDialog)

5. Microsoft Dynamics CRM Roadmap

6.   AD and MS CRM sync, how? – discussion

7.How to find accounts without activity

8. Performance issue – for CRM online – “I have spend several months working on performance. We found the location, internet connection, PC configuration were all external factors. When we started looking inside of the database, we found java script on the form or number of grids all impacted the form load time. The tools (dynamics.com/tools/diagnostics/diag.aspx.) is a great starting point for what is causing the issues”

9. Technet Library – about upgrade from CRM 2011 to CRM 2016

10.  Tips when migrating using Excel

11. upgrade to Microsoft Dynamics CRM 2016 — plan and tools

> 9 Tips for upgrate to CRM 2016

12. https://www.linkedin.com/pulse/dynamics-crm-2016-just-start-roohi-shaikh – list of CRM 2016 update 0.1 features

13. Microsoft Dynamics CRM Outlook Client synchronization rules

14  Anyone have a good document on setting up and utilizing the Product Catalog/Pricelist?

15  Securing Records By a Field Value in Dynamics CRM

16 Solutions in CRM 2016

17 useful article –  Release management, Solution packager

18 Dynamics CRM page load is slow and Optimize performance using Microsoft CRM Form Load Performance Analyzer

Advertisements

The best example of support article

All parts of article are good, text was split to logical areas.  How to Enable Tracing in Microsoft Dynamics CRM

Исследуем базы данных с помощью T-SQL

Исследуем базы данных с помощью T-SQLперевод
(http:// habrahabr.ru/post/241079/ )   sqlservercentral.com,  https:// www. simple-talk.com/sql/database-administration/exploring-your-sql-server-databases-with-t-sql/
Как dba и консультант по оптимизации производительности SQL Server в Ambient Consulting, я часто сталкиваюсь с необходимостью анализа узких мест производительности на экземплярах SQL Server, которые вижу первый раз в жизни. Это может быть сложной задачей. Как правило, у большинства компаний нет документации по их базам данных. А если есть, то она устарела, или же её поиск занимает несколько дней.В этой статье я поделюсь базовым набором скриптов, раскапывающим информацию о метаданных с помощью системных функций, хранимых процедур, таблиц, dmv. Вместе они раскрывают все секреты баз данных на нужном экземпляре – их размер, расположение файлов, их дизайн, включая столбцы, типы данных, значения по умолчанию, ключи и индексы.Если вы когда-нибудь пытались получить часть этой информации, с помощью GUI, я думаю вы будете приятно удивлены количеством той информации, которая, с помощью этих скриптов, получается мнгновенно.Как и с любыми скриптами, сначала проверьте их в тестовом окружении, прежде чем запускать в продакшене. Я бы рекомендовал вам погонять их на тестовых базах MS, таких как AdventureWorks или pubs.Ну, хватит слов, давайте я покажу скрипты!

Изучаем сервера

Начнём с запросов, предоставляющих информацию о ваших серверах.

Базовая информация

Во-первых, несколько простых @@Функций, которые предоставят нам базовую информацию.

-- Имена сервера и экземпляра 
Select @@SERVERNAME as [Server\Instance]; 

-- версия SQL Server 
Select @@VERSION as SQLServerVersion; 

-- экземпляр SQL Server 
Select @@ServiceName AS ServiceInstance;

 -- Текущая БД (БД, в контексте которой выполняется запрос)
Select DB_NAME() AS CurrentDB_Name;

Как долго ваш SQL Server работает после последнего перезапуска? Помните, что системная база данных tempdb пересоздаётся при каждом перезапуске SQL Server. Вот один из методов определения времени последнего перезапуска сервера.

SELECT  @@Servername AS ServerName ,
        create_date AS  ServerStarted ,
        DATEDIFF(s, create_date, GETDATE()) / 86400.0 AS DaysRunning ,
        DATEDIFF(s, create_date, GETDATE()) AS SecondsRunnig
FROM    sys.databases
WHERE   name = 'tempdb'; 

GO

Связанные сервера

Связанные сервера – это соединения, позволяющие SQL Server’у обращаться к другим серверам с данными. Распределённые запросы могут быть запущенны на разных связанных серверах. Полезно знать – является ли ваш сервер баз данных изолированным от других, или он связан с другими серверами.

EXEC sp_helpserver; 

--OR 

EXEC sp_linkedservers; 

--OR 

SELECT  @@SERVERNAME AS Server ,
        Server_Id AS  LinkedServerID ,
        name AS LinkedServer ,
        Product ,
        Provider ,
        Data_Source ,
        Modify_Date
FROM    sys.servers
ORDER BY name; 

GO

Список всех баз данных

Во-первых, получим список всех баз данных на сервере. Помните, что на любом сервере есть четыре или пять системных баз данных (master, model, msdb, tempdb и distribution, если вы пользуетесь репликацией). Вы, вероятно, захотите исключить эти базы в следующих запросах. Очень просто увидеть список баз данных в SSMS, но, эти запросы будут нашими «строительными блоками» для более сложных запросов.

Есть несколько путей для получения списка всех БД на T-SQL и ниже вы увидите некоторые из них. Каждый метод возвращает похожий результат, но с некоторыми отличиями.

EXEC sp_helpdb; 

--OR 

EXEC sp_Databases; 

--OR 

SELECT  @@SERVERNAME AS Server ,
        name AS DBName ,
        recovery_model_Desc AS RecoveryModel ,
        Compatibility_level AS CompatiblityLevel ,
        create_date ,
        state_desc
FROM    sys.databases
ORDER BY Name; 

--OR 

SELECT  @@SERVERNAME AS Server ,
        d.name AS DBName ,
        create_date ,
        compatibility_level ,
        m.physical_name AS FileName
FROM    sys.databases d
        JOIN sys.master_files m ON d.database_id = m.database_id
WHERE   m.[type] = 0 -- data files only
ORDER BY d.name; 

GO

Последний бэкап?

Стоп! Прежде чем двигаться дальше, каждый хороший dba должен узнать есть ли у него свежий бэкап.

SELECT  @@Servername AS ServerName ,
        d.Name AS DBName ,
        MAX(b.backup_finish_date) AS LastBackupCompleted
FROM    sys.databases d
        LEFT OUTER JOIN msdb..backupset b
                    ON b.database_name = d.name
                       AND b.[type] = 'D'
GROUP BY d.Name
ORDER BY d.Name;

Будет лучше, если вы сразу узнаете путь к файлу с последним бэкапом.

SELECT  @@Servername AS ServerName ,
        d.Name AS DBName ,
        b.Backup_finish_date ,
        bmf.Physical_Device_name
FROM    sys.databases d
        INNER JOIN msdb..backupset b ON b.database_name = d.name
                                        AND b.[type] = 'D'
        INNER JOIN msdb.dbo.backupmediafamily bmf ON b.media_set_id = bmf.media_set_id
ORDER BY d.NAME ,
        b.Backup_finish_date DESC; 

GO

Активные пользовательские соединения

Хорошо было бы понимать какие БД сейчас используются, особенно, если вы собираетесь разбираться с проблемами производительности.

Примечание переводчика: это будет работать только в SQL Server 2012 и выше, в предыдущих редакциях, в dmv sys.dm_exec_sessions отсутствовал столбец database_id. Чтобы узнать в каких БД в данный момент работают пользователи, можно воспользоваться sp_who.

-- Похожая информация, может быть получена с помощью sp_who 

SELECT  @@Servername AS Server ,
        DB_NAME(database_id) AS DatabaseName ,
        COUNT(database_id) AS Connections ,
        Login_name AS  LoginName ,
        MIN(Login_Time) AS Login_Time ,
        MIN(COALESCE(last_request_end_time, last_request_start_time))
                                                         AS  Last_Batch
FROM    sys.dm_exec_sessions
WHERE   database_id > 0
        AND DB_NAME(database_id) NOT IN ( 'master', 'msdb' )
GROUP BY database_id ,
         login_name
ORDER BY DatabaseName;

Изучаем базы данных

Давайте заглянем поглубже и посмотрим, как мы можем собрать информацию об объектах во всех ваших БД, используя различные представления каталога и dmv. Большинство из запросов, представленных в этом разделе, смотрят «внутрь» только одной БД, поэтому не забывайте выбирать нужную БД в SSMS или с помощью команды use database. Также помните, что вы всегда можете посмотреть в контексте какой БД будет выполнен запрос, с помощью select db_name().

Системная таблица sys.objects одна из ключевых для сбора информации об объектах, составляющих вашу модель данных.

-- В примере U - таблицы
-- Попробуйте подставить другие значения type в WHERE

USE MyDatabase;
GO

SELECT  *
FROM    sys.objects
WHERE   type = 'U';

Ниже представлен список типов объектов, информацию о которых мы можем получить (смотрите документацию на sys.objects в MSDN)

sys.objects.type

AF = статистическая функция (среда CLR);
C = ограничение CHECK;
D = DEFAULT (ограничение или изолированный);
F = ограничение FOREIGN KEY;
PK = ограничение PRIMARY KEY;
P = хранимая процедура SQL;
PC = хранимая процедура сборки (среда CLR);
FN = скалярная функция SQL;
FS = скалярная функция сборки (среда CLR);
FT = возвращающая табличное значение функция сборки (среда CLR);
R = правило (старый стиль, изолированный);
RF = процедура фильтра репликации;
S = системная базовая таблица;
SN = синоним;
SQ = очередь обслуживания;
TA = триггер DML сборки (среда CLR);
TR = триггер DML SQL;
IF = встроенная возвращающая табличное значение функция SQL;
TF = возвращающая табличное значение функция SQL;
U = таблица (пользовательская);
UQ = ограничение UNIQUE;
V = представление;
X = расширенная хранимая процедура;
IT = внутренняя таблица.

Другие представления каталога, такие как sys.tables и sys.views, обращаются к sys.objects и предоставляют информацию о конкретном типе объектов. С этими представлениями, плюс функцией OBJECTPROPERTY, мы можем получить огромное количество информации по каждому из объектов, составляющих нашу схему БД.

Расположение файлов баз данных

Физическое расположение выбранной БД, включая основной файл данных (mdf), и файл журнала транзакций (ldf), могут быть получены с помощью этих запросов.

EXEC sp_Helpfile; 

--OR 

SELECT  @@Servername AS Server ,
        DB_NAME() AS DB_Name ,
        File_id ,
        Type_desc ,
        Name ,
        LEFT(Physical_Name, 1) AS Drive ,
        Physical_Name ,
        RIGHT(physical_name, 3) AS Ext ,
        Size ,
        Growth
FROM    sys.database_files
ORDER BY File_id; 

GO

Таблицы

Конечно, Object Explorer в SSMS показывает полный список таблиц в выбранной БД, но часть информации с помощью GUI получить сложнее, чем с помощью скриптов. Стандарт ANSI предполагает обращение к представлениям INFORMATION_SCHEMA, но они не предоставят информацию об объектах, которые не являются частью стандарта (такие как триггеры, extended procedures и т.д.), поэтому лучше использовать представления каталога SQL Server.

EXEC sp_tables; -- Помните, что этот метод вернёт и таблицы, и представления 

--OR 

SELECT  @@Servername AS ServerName ,
        TABLE_CATALOG ,
        TABLE_SCHEMA ,
        TABLE_NAME
FROM     INFORMATION_SCHEMA.TABLES
WHERE   TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_NAME ;

--OR

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        o.name AS 'TableName' ,
        o.[Type] ,
        o.create_date
FROM    sys.objects o
WHERE   o.Type = 'U' -- User table 
ORDER BY o.name;

--OR 

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        t.Name AS TableName,
        t.[Type],
        t.create_date
FROM    sys.tables t
ORDER BY t.Name;

GO

Количество записей в таблице

Если вы ничего не знаете о таблице, то все таблицы одинаково важны. Чем больше вы узнаёте о таблицах, тем больше вы их разделяете на условно более важные и условно менее важные. В целом, таблицы с огромным количеством записей чаще оказывают серьёзное влияние на производительность.

В SSMS мы можем нажать правой кнопкой мыши на любую таблицу, открыть свойства на вкладке Storage и увидеть количество записей в таблице.

Довольно тяжело собрать вручную эту информацию обо всех таблицах. Опять же, если мы будем писать SELECT COUNT(*) FROM TABLENAME для каждой таблицы, нам придётся очень много печатать.

Намного удобнее использовать T-SQL для генерирования скрипта. Скрипт, приведённый ниже, сгенерирует набор инструкций T-SQL для получения количества строк в каждой таблице текущей базы данных. Просто выполните его, скопируйте результат в новое окно и запустите.

SELECT  'Select ''' + DB_NAME() + '.' + SCHEMA_NAME(SCHEMA_ID) + '.'
        + LEFT(o.name, 128) + ''' as DBName, count(*) as Count From ' + o.name
        + ';' AS ' Script generator to get counts for all tables'
FROM    sys.objects o
WHERE   o.[type] = 'U'
ORDER BY o.name;

GO

Примечание переводчика: у меня запрос не работал, добавил схему к имени таблицы.

SELECT  'Select ''' + DB_NAME() + '.' + SCHEMA_NAME(SCHEMA_ID) + '.'
        + LEFT(o.name, 128) + ''' as DBName, count(*) as Count From ' + SCHEMA_NAME(SCHEMA_ID) + '.' + o.name
        + ';' AS ' Script generator to get counts for all tables'
FROM    sys.objects o
WHERE   o.[type] = 'U'
ORDER BY o.name;

sp_msForEachTable

Sp_msforeachtable – это недокументированная функция, которая «проходит» по всем таблицам в БД и выполняет запрос, подставляя вместо ‘?’ имя текущей таблицы. Так же существует похожая функция sp_msforeachdb, работающая на уровне баз данных.

Известно несколько проблем с этой недокументированной функцией, например, использование спецсимволов в именах объектов. Т.е. если имя таблицы или базы данных содержит знак ‘-‘, хранимая процедура, листинг которой ниже, завершится с ошибкой.

CREATE TABLE #rowcount
    ( Tablename VARCHAR(128) ,
      Rowcnt INT ); 

EXEC sp_MSforeachtable 'insert into #rowcount select ''?'', count(*) from ?' 

SELECT  *
FROM    #rowcount
ORDER BY Tablename ,
        Rowcnt; 

DROP TABLE #rowcount;

Самый быстрый способ получения количества записей – кластерный индекс

Все предыдущие метода использовали COUNT(*), который медленно отрабатывает, если в таблице больше чем 500K записей.

Самый быстрый способ получения количества записей в таблице – получать количество записей в кластерном индексе или куче. Помните, что хоть этот метод и самый быстрый, MS говорит, что информация о количестве записей индекса и реальное количество строк в таблице может не совпадать, из-за того, что на обновление информации требуется хоть и небольшое, но время. В большинстве же случаев, эти значения или одинаковы, или очень-очень близки и вскоре станут одинаковыми.

-- Самый быстрый путь получения количества записей
-- Hint: получайте из индекса, а не таблицы

SELECT  @@ServerName AS Server ,
        DB_NAME() AS DBName ,
        OBJECT_SCHEMA_NAME(p.object_id) AS SchemaName ,
        OBJECT_NAME(p.object_id) AS TableName ,
        i.Type_Desc ,
        i.Name AS IndexUsedForCounts ,
        SUM(p.Rows) AS Rows
FROM    sys.partitions p
        JOIN sys.indexes i ON i.object_id = p.object_id
                              AND i.index_id = p.index_id
WHERE   i.type_desc IN ( 'CLUSTERED', 'HEAP' )
                             -- This is key (1 index per table) 
        AND OBJECT_SCHEMA_NAME(p.object_id) <> 'sys'
GROUP BY p.object_id ,
        i.type_desc ,
        i.Name
ORDER BY SchemaName ,
        TableName; 

-- OR 

-- Похожий метод получения количества записей, но с использованием DMV dm_db_partition_stats 
SELECT  @@ServerName AS ServerName ,
        DB_NAME() AS DBName ,
        OBJECT_SCHEMA_NAME(ddps.object_id) AS SchemaName ,
        OBJECT_NAME(ddps.object_id) AS TableName ,
        i.Type_Desc ,
        i.Name AS IndexUsedForCounts ,
        SUM(ddps.row_count) AS Rows
FROM    sys.dm_db_partition_stats ddps
        JOIN sys.indexes i ON i.object_id = ddps.object_id
                              AND i.index_id = ddps.index_id
WHERE   i.type_desc IN ( 'CLUSTERED', 'HEAP' )
                              -- This is key (1 index per table) 
        AND OBJECT_SCHEMA_NAME(ddps.object_id) <> 'sys'
GROUP BY ddps.object_id ,
        i.type_desc ,
        i.Name
ORDER BY SchemaName ,
        TableName;

GO

Поиск куч (таблиц без кластерных индексов)

Работа с кучами – это как работа с плоским файлом, вместо базы данных. Если вы хотите гарантированно получать полное сканирование таблицы при выполнении любого запроса, используйте кучи. Обычно я рекомендую добавлять primary key ко всем таблицам-кучам.

-- Кучи (метод 1)

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        t.Name AS HeapTable ,
        t.Create_Date
FROM    sys.tables t
        INNER JOIN sys.indexes i ON t.object_id = i.object_id
                                    AND i.type_desc = 'HEAP'
ORDER BY t.Name 

--OR 
-- Кучи (Метод 2) 

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        t.Name AS HeapTable ,
        t.Create_Date
FROM    sys.tables t
WHERE    OBJECTPROPERTY(OBJECT_ID, 'TableHasClustIndex') = 0
ORDER BY t.Name; 

--OR 
-- Кучи (Метод 3) + количество записей

SELECT  @@ServerName AS Server ,
        DB_NAME() AS DBName ,
        OBJECT_SCHEMA_NAME(ddps.object_id) AS SchemaName ,
        OBJECT_NAME(ddps.object_id) AS TableName ,
        i.Type_Desc ,
        SUM(ddps.row_count) AS Rows
FROM    sys.dm_db_partition_stats AS ddps
        JOIN sys.indexes i ON i.object_id = ddps.object_id
                              AND i.index_id = ddps.index_id
WHERE   i.type_desc = 'HEAP'
        AND OBJECT_SCHEMA_NAME(ddps.object_id) <> 'sys'
GROUP BY ddps.object_id ,
        i.type_desc
ORDER BY TableName;

Разбираемся с активностью в таблице

При работах по оптимизации производительности, очень важно знать какие таблицы активно читаются, а в какие идёт активная запись. Ранее мы узнали сколько записей в наших таблицах, сейчас посмотрим как часто в них пишут и читают.

Помните, что эта информация из dmv, очищается при каждом перезапуске SQL Server. Чем дольше сервер работает, тем более надёжна статистика. Я чувствую себя намного более уверенно со статистикой, собранной за 30 дней, чем со статистикой, собранной за неделю.

-- Чтение/запись таблицы
-- Кучи не рассматриваются, у них нет индексов
-- Только те таблицы, к которым обращались после запуска SQL Server

SELECT  @@ServerName AS ServerName ,
        DB_NAME() AS DBName ,
        OBJECT_NAME(ddius.object_id) AS TableName ,
        SUM(ddius.user_seeks + ddius.user_scans + ddius.user_lookups)
                                                               AS  Reads ,
        SUM(ddius.user_updates) AS Writes ,
        SUM(ddius.user_seeks + ddius.user_scans + ddius.user_lookups
            + ddius.user_updates) AS [Reads&Writes] ,
        ( SELECT    DATEDIFF(s, create_date, GETDATE()) / 86400.0
          FROM      master.sys.databases
          WHERE     name = 'tempdb'
        ) AS SampleDays ,
        ( SELECT    DATEDIFF(s, create_date, GETDATE()) AS SecoundsRunnig
          FROM      master.sys.databases
          WHERE     name = 'tempdb'
        ) AS SampleSeconds
FROM    sys.dm_db_index_usage_stats ddius
        INNER JOIN sys.indexes i ON ddius.object_id = i.object_id
                                     AND i.index_id = ddius.index_id
WHERE    OBJECTPROPERTY(ddius.object_id, 'IsUserTable') = 1
        AND ddius.database_id = DB_ID()
GROUP BY OBJECT_NAME(ddius.object_id)
ORDER BY [Reads&Writes] DESC;

GO

Намного более продвинутая версия этого запроса представлена курсором, собирающим информацию по всем таблицам всех баз данных на сервере. Вообще, я не фанат курсоров из-за их невысокой производительности, но перемещение по разным базам данных – это отличное применение для них.

-- Операции чтения и записи
-- Кучи пропущены, у них нет индексов
-- Только таблицы, использовавшиеся после перезапуска SQL Server
-- В запросе используется курсор для получения информации во всех БД
-- Единый отчёт, хранится в tempdb

DECLARE DBNameCursor CURSOR
FOR
    SELECT  Name
    FROM    sys.databases
    WHERE    Name NOT IN ( 'master', 'model', 'msdb', 'tempdb',
                            'distribution' )
    ORDER BY Name; 

DECLARE @DBName NVARCHAR(128) 

DECLARE @cmd VARCHAR(4000) 

IF OBJECT_ID(N'tempdb..TempResults') IS NOT NULL
    BEGIN 
        DROP TABLE tempdb..TempResults 
    END 

CREATE TABLE tempdb..TempResults
    (
      ServerName NVARCHAR(128) ,
      DBName NVARCHAR(128) ,
      TableName NVARCHAR(128) ,
      Reads INT ,
      Writes INT ,
      ReadsWrites INT ,
      SampleDays DECIMAL(18, 8) ,
      SampleSeconds INT
    ) 

OPEN DBNameCursor 

FETCH NEXT FROM DBNameCursor INTO @DBName 
WHILE @@fetch_status = 0
    BEGIN 

---------------------------------------------------- 
-- Print @DBName 

        SELECT   @cmd = 'Use ' + @DBName + '; ' 
        SELECT   @cmd = @cmd + ' Insert Into tempdb..TempResults 
SELECT @@ServerName AS ServerName, 
DB_NAME() AS DBName, 
object_name(ddius.object_id) AS TableName , 
SUM(ddius.user_seeks 
+ ddius.user_scans 
+ ddius.user_lookups) AS Reads, 
SUM(ddius.user_updates) as Writes, 
SUM(ddius.user_seeks 
+ ddius.user_scans 
+ ddius.user_lookups 
+ ddius.user_updates) as ReadsWrites, 
(SELECT datediff(s,create_date, GETDATE()) / 86400.0 
FROM sys.databases WHERE name = ''tempdb'') AS SampleDays, 
(SELECT datediff(s,create_date, GETDATE()) 
FROM sys.databases WHERE name = ''tempdb'') as SampleSeconds 
FROM sys.dm_db_index_usage_stats ddius 
INNER JOIN sys.indexes i
ON ddius.object_id = i.object_id 
AND i.index_id = ddius.index_id 
WHERE objectproperty(ddius.object_id,''IsUserTable'') = 1 --True 
AND ddius.database_id = db_id() 
GROUP BY object_name(ddius.object_id) 
ORDER BY ReadsWrites DESC;' 

--PRINT @cmd 
        EXECUTE (@cmd) 

----------------------------------------------------- 

        FETCH NEXT FROM DBNameCursor INTO @DBName 
    END 

CLOSE DBNameCursor 

DEALLOCATE DBNameCursor 

SELECT  *
FROM    tempdb..TempResults
ORDER BY DBName ,
        TableName; 
--DROP TABLE tempdb..TempResults;

Примечание переводчика: курсор не отработает, если у вас в списке есть базы данных с состоянием, отличным от ONLINE.

Представления

Представления – это, условно говоря, запросы, хранящиеся в БД. Вы можете думать о них, как о виртуальных таблицах. Данные не хранятся в представлениях, но в наших запросах мы ссылаемся на них точно так же, как и на таблицы.

В SQL Server, в некоторых случаях, мы можем обновлять данные с использованием представления. Чтобы получить представление «только для чтения», можно использовать SELECT DISTINCT при его создании. Данные «через» представление можно менять только в том случае, если каждой строке представления соответствует только одна строка в «базовой» таблице. Любое представление, не отвечающее этому критерию, т.е. построенное на нескольких таблицах, или с использованием группировок, агрегатных функций и вычислений, будет доступно только для чтения.

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        o.name AS ViewName ,
        o.[Type] ,
        o.create_date
FROM    sys.objects o
WHERE   o.[Type] = 'V' -- View 
ORDER BY o.NAME  

--OR 

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        Name AS ViewName ,
        create_date
FROM    sys.Views
ORDER BY Name 

--OR

SELECT  @@Servername AS ServerName ,
        TABLE_CATALOG ,
        TABLE_SCHEMA ,
        TABLE_NAME ,
        TABLE_TYPE
FROM     INFORMATION_SCHEMA.TABLES
WHERE   TABLE_TYPE = 'VIEW'
ORDER BY TABLE_NAME 

--OR 

-- CREATE VIEW Code 
SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DB_Name ,
        o.name AS 'ViewName' ,
        o.Type ,
        o.create_date ,
        sm.[DEFINITION] AS 'View script'
FROM    sys.objects o
        INNER JOIN sys.sql_modules sm ON o.object_id = sm.OBJECT_ID
WHERE   o.Type = 'V' -- View 
ORDER BY o.NAME;

GO

Синонимы

Несколько раз в моей карьере я сталкивался с ситуацией, когда не мог понять к какой же таблице обращается запрос. Представьте простой запрос SELECT * FROM Client. Я ищу таблицу под именем Client, но я не могу найти её. Хорошо, думаю я, должно быть это представление, ищу представление с именем Client и всё равно не могу найти. Может быть я ошибся базой данных? В итоге выясняется, что Client – это синоним для покупателей и таблица, на самом деле, называется Customer. Отдел маркетинга хотел обращаться к этой таблице как к Client и из-за этого был создан синоним. К счастью, использование синонимов – это редкость, но разбирательства могут вызвать определённые затруднения, если вы к ним не готовы.

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        o.name AS ViewName ,
        o.Type ,
        o.create_date
FROM    sys.objects o
WHERE   o.[Type] = 'SN' -- Synonym 
ORDER BY o.NAME;

--OR 
-- дополнительная информация о синонимах

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        s.name AS synonyms ,
        s.create_date ,
        s.base_object_name
FROM    sys.synonyms s
ORDER BY s.name;

GO

Хранимые процедуры

Хранимые процедуры – это группа скриптов, которые компилируются в единственный план выполнения. Мы можем использовать представления каталога, чтобы определить какие ХП созданы, какие действия они выполняют и над какими таблицами.

-- Хранимые процедуры 
SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        o.name AS StoredProcedureName ,
        o.[Type] ,
        o.create_date
FROM    sys.objects o
WHERE   o.[Type] = 'P' -- Stored Procedures 
ORDER BY o.name

--OR 
-- Дополнительная информация о ХП 

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DB_Name ,
        o.name AS 'ViewName' ,
        o.[type] ,
        o.Create_date ,
        sm.[definition] AS 'Stored Procedure script'
FROM    sys.objects o
        INNER JOIN sys.sql_modules sm ON o.object_id = sm.object_id
WHERE   o.[type] = 'P' -- Stored Procedures 
        -- AND sm.[definition] LIKE '%insert%'
        -- AND sm.[definition] LIKE '%update%'
        -- AND sm.[definition] LIKE '%delete%'
        -- AND sm.[definition] LIKE '%tablename%'
ORDER BY o.name;

GO

Добавив простое условие в WHERE мы можем получить информацию только о тех хранимых процедурах, которые, например, выполняют операции INSERT.

WHERE   o.[type]  = 'P' -- Stored Procedures 
        AND sm.definition LIKE '%insert%'
ORDER BY o.name
…

Немного модифицировав условие в WHERE, мы можем собрать информацию о ХП, производящих обновление, удаление или же обращающихся к определённым таблицам.

Функции

Функции хранятся в SQL Server, принимают какие-либо параметры и выполняют определённые действия, либо вычисления, после чего возвращают результат.

-- Функции

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DB_Name ,
        o.name AS 'Functions' ,
        o.[Type] ,
        o.create_date
FROM    sys.objects o
WHERE   o.Type = 'FN' -- Function 
ORDER BY o.NAME;

--OR 
-- Дополнительная информация о функциях

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DB_Name ,
        o.name AS 'FunctionName' ,
        o.[type] ,
        o.create_date ,
        sm.[DEFINITION] AS 'Function script'
FROM    sys.objects o
        INNER JOIN sys.sql_modules sm ON o.object_id = sm.OBJECT_ID
WHERE   o.[Type] = 'FN' -- Function 
ORDER BY o.NAME;

GO

Триггеры

Триггер – это что-то вроде хранимой процедуры, которая выполняется в ответ на определённые действия с той таблицей, которой этот триггер принадлежит. Например, мы можем создать INSERT, UPDATE и DELETE триггеры.

-- Триггеры

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        parent.name AS TableName ,
        o.name AS TriggerName ,
        o.[Type] ,
        o.create_date
FROM    sys.objects o
        INNER JOIN sys.objects parent ON o.parent_object_id = parent.object_id
WHERE   o.Type = 'TR' -- Triggers 
ORDER BY parent.name ,
        o.NAME 

--OR 

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DB_Name ,
        Parent_id ,
        name AS TriggerName ,
        create_date
FROM    sys.triggers
WHERE   parent_class = 1
ORDER BY name;

--OR 
-- Дополнительная информация о триггерах

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DB_Name ,
        OBJECT_NAME(Parent_object_id) AS TableName ,
        o.name AS 'TriggerName' ,
        o.Type ,
        o.create_date ,
        sm.[DEFINITION] AS 'Trigger script'
FROM    sys.objects o
        INNER JOIN sys.sql_modules sm ON o.object_id = sm.OBJECT_ID
WHERE   o.Type = 'TR' -- Triggers 
ORDER BY o.NAME;

GO

CHECK-ограничения

CHECK-ограничения – это неплохое средство для реализации бизнес-логики в базе данных. Например, некоторые поля должны быть положительными, или отрицательными, или дата в одном столбце должна быть больше даты в другом.

-- Check Constraints 

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        parent.name AS 'TableName' ,
        o.name AS 'Constraints' ,
        o.[Type] ,
        o.create_date
FROM    sys.objects o
        INNER JOIN sys.objects parent
               ON o.parent_object_id = parent.object_id
WHERE   o.Type = 'C' -- Check Constraints 
ORDER BY parent.name ,
        o.name 

--OR 
--CHECK constriant definitions

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        OBJECT_SCHEMA_NAME(parent_object_id) AS SchemaName ,
        OBJECT_NAME(parent_object_id) AS TableName ,
        parent_column_id AS  Column_NBR ,
        Name AS  CheckConstraintName ,
        type ,
        type_desc ,
        create_date ,
        OBJECT_DEFINITION(object_id) AS CheckConstraintDefinition
FROM    sys.Check_constraints
ORDER BY TableName ,
        SchemaName ,
        Column_NBR 

GO

Углубляемся в модель данных

Ранее, мы использовали скрипты, которые дали нам представление о «верхнем уровне» объектов, составляющих нашу базу данных. Иногда нам нужно получить больше данных о таблице, включая столбцы, их типы данных, какие значения по умолчанию заданы, какие ключи и индексы существуют (или должны существовать) и т.д.

Запросы, представленные в этом разделе, предоставляют средства почти что реверс-инжиниринга существующей модели данных.

Столбцы

Следующий скрипт описывает таблицы и столбцы из всей базы данных. Результат этого запроса, можно скопировать в Excel, где можно настроить фильтры и сортировку и хорошо разобраться с типами данных, использующимися в БД. Так же, обратите внимание на столбцы с одинаковыми именами, но разными типами данных.

SELECT  @@Servername AS Server ,
        DB_NAME() AS DBName ,
        isc.Table_Name AS TableName ,
        isc.Table_Schema AS SchemaName ,
        Ordinal_Position AS  Ord ,
        Column_Name ,
        Data_Type ,
        Numeric_Precision AS  Prec ,
        Numeric_Scale AS  Scale ,
        Character_Maximum_Length AS LEN , -- -1 means MAX like Varchar(MAX) 
        Is_Nullable ,
        Column_Default ,
        Table_Type
FROM     INFORMATION_SCHEMA.COLUMNS isc
        INNER JOIN  information_schema.tables ist
              ON isc.table_name = ist.table_name 
--      WHERE Table_Type = 'BASE TABLE' -- 'Base Table' or 'View' 
ORDER BY DBName ,
        TableName ,
        SchemaName ,
        Ordinal_position;  

-- Имена столбцов и количество повторов
-- Используется для поиска одноимённых столбцов с разными типами данных/длиной

SELECT  @@Servername AS Server ,
        DB_NAME() AS DBName ,
        Column_Name ,
        Data_Type ,
        Numeric_Precision AS  Prec ,
        Numeric_Scale AS  Scale ,
        Character_Maximum_Length ,
        COUNT(*) AS Count
FROM     information_schema.columns isc
        INNER JOIN  information_schema.tables ist
               ON isc.table_name = ist.table_name
WHERE   Table_type = 'BASE TABLE'
GROUP BY Column_Name ,
        Data_Type ,
        Numeric_Precision ,
        Numeric_Scale ,
        Character_Maximum_Length; 

-- Информация по используемым типам данных

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        Data_Type ,
        Numeric_Precision AS  Prec ,
        Numeric_Scale AS  Scale ,
        Character_Maximum_Length AS [Length] ,
        COUNT(*) AS COUNT
FROM     information_schema.columns isc
        INNER JOIN  information_schema.tables ist
               ON isc.table_name = ist.table_name
WHERE   Table_type = 'BASE TABLE'
GROUP BY Data_Type ,
        Numeric_Precision ,
        Numeric_Scale ,
        Character_Maximum_Length
ORDER BY Data_Type ,
        Numeric_Precision ,
        Numeric_Scale ,
        Character_Maximum_Length  

-- Large object data types or Binary Large Objects(BLOBs) 
-- Помните, что индексы по этим таблицам не могут быть перестроены в режиме "online"

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        isc.Table_Name ,
        Ordinal_Position AS  Ord ,
        Column_Name ,
        Data_Type AS  BLOB_Data_Type ,
        Numeric_Precision AS  Prec ,
        Numeric_Scale AS  Scale ,
        Character_Maximum_Length AS [Length]
FROM     information_schema.columns isc
        INNER JOIN  information_schema.tables ist
               ON isc.table_name = ist.table_name
WHERE   Table_type = 'BASE TABLE'
        AND ( Data_Type IN ( 'text', 'ntext', 'image', 'XML' )
              OR ( Data_Type IN ( 'varchar', 'nvarchar', 'varbinary' )
                   AND Character_Maximum_Length = -1
                 )
            ) -- varchar(max), nvarchar(max), varbinary(max) 
ORDER BY isc.Table_Name ,
        Ordinal_position;

Значения по умолчанию

Значение по умолчанию – это значение, которое будет сохранено, если никакого значения для столбца не будет задано при вставке. Зачастую, для столбцов хранящих дату ставят get_date(). Также, значения по умолчанию используются для аудита – вставляется system_user для определения учётной записи пользователя, совершившего определённое действие.

-- Table Defaults 

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        parent.name AS TableName ,
        o.name AS Defaults ,
        o.[Type] ,
        o.Create_date
FROM    sys.objects o
        INNER JOIN sys.objects parent
               ON o.parent_object_id = parent.object_id
WHERE   o.[Type] = 'D' -- Defaults 
ORDER BY parent.name ,
        o.NAME

--OR 
-- Column Defaults 

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DB_Name ,
        OBJECT_SCHEMA_NAME(parent_object_id) AS SchemaName ,
        OBJECT_NAME(parent_object_id) AS TableName ,
        parent_column_id AS  Column_NBR ,
        Name AS DefaultName ,
        [type] ,
        type_desc ,
        create_date ,
        OBJECT_DEFINITION(object_id) AS Defaults
FROM    sys.default_constraints
ORDER BY TableName ,
        Column_NBR 

--OR 
-- Column Defaults 

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DB_Name ,
        OBJECT_SCHEMA_NAME(t.object_id) AS SchemaName ,
        t.Name AS TableName ,
        c.Column_ID AS Ord ,
        c.Name AS Column_Name ,
        OBJECT_NAME(default_object_id) AS DefaultName ,
        OBJECT_DEFINITION(default_object_id) AS Defaults
FROM    sys.Tables t
        INNER JOIN sys.columns c ON t.object_id = c.object_id
WHERE    default_object_id <> 0
ORDER BY TableName ,
        SchemaName ,
        c.Column_ID 

GO

Вычисляемые столбцы

Вычисляемые столбцы – это столбцы, значения в которых вычисляются на основании, как правило, значений в других столбцах таблицы.

-- Вычисляемые столбцы

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        OBJECT_SCHEMA_NAME(object_id) AS SchemaName ,
        OBJECT_NAME(object_id) AS Tablename ,
        Column_id ,
        Name AS  Computed_Column ,
        [Definition] ,
        is_persisted
FROM    sys.computed_columns
ORDER BY SchemaName ,
        Tablename ,
        [Definition]; 

--Or 
-- Computed Columns 

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        OBJECT_SCHEMA_NAME(t.object_id) AS SchemaName,
        t.Name AS TableName ,
        c.Column_ID AS Ord ,
        c.Name AS Computed_Column
FROM    sys.Tables t
        INNER JOIN sys.Columns c ON t.object_id = c.object_id
WHERE   is_computed = 1
ORDER BY t.Name ,
        SchemaName ,
        c.Column_ID 

GO

Столбцы identity

Столбцы IDENTITY автоматически заполняются системой уникальными значениями. Обычно используются для хранения порядкового номера записи в таблице.

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DBName ,
        OBJECT_SCHEMA_NAME(object_id) AS SchemaName ,
        OBJECT_NAME(object_id) AS TableName ,
        Column_id ,
        Name AS  IdentityColumn ,
        Seed_Value ,
        Last_Value
FROM    sys.identity_columns
ORDER BY SchemaName ,
        TableName ,
        Column_id; 

GO

Ключи и индексы

Как я писал ранее, наличие первичного ключа и соответствующего индекса у таблицы – это одна из best practice. Ещё одна best practice заключается в том, что внешние ключи так же должны иметь индекс, построенный по столбцам, входящим во внешний ключ. Индексы, построенные «по внешним ключам» отлично подходят для соединения таблиц. Эти индексы так же хорошо сказываются на производительности при удалении записей.

Какие индексы у нас есть?

Скрипт для поиска всех индексов во всех таблицах текущей БД.

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DB_Name ,
        o.Name AS TableName ,
        i.Name AS IndexName
FROM    sys.objects o
        INNER JOIN sys.indexes i ON o.object_id = i.object_id
WHERE   o.Type = 'U' -- User table 
        AND LEFT(i.Name, 1) <> '_' -- Remove hypothetical indexes 
ORDER BY o.NAME ,
        i.name; 

GO

Каких индексов не хватает?

На основании ранее исполнявшихся запросов, SQL Server предоставляет информацию об отсутствующих индексах в БД, создание которых может увеличить производительность.

Не добавляйте эти индексы вслепую. Я бы подумал о каждом из предложенных индексов. Использование включенных столбцов, например, может аукнуться серьёзным увеличением объёмов.

-- Отсутствующие индексы из DMV

SELECT  @@ServerName AS ServerName ,
        DB_NAME() AS DBName ,
        t.name AS 'Affected_table' ,
        ( LEN(ISNULL(ddmid.equality_columns, N'')
              + CASE WHEN ddmid.equality_columns IS NOT NULL
                          AND ddmid.inequality_columns IS NOT NULL THEN ','
                     ELSE ''
                END) - LEN(REPLACE(ISNULL(ddmid.equality_columns, N'')
                                   + CASE WHEN ddmid.equality_columns
                                                             IS NOT NULL
                                               AND ddmid.inequality_columns
                                                             IS NOT NULL
                                          THEN ','
                                          ELSE ''
                                     END, ',', '')) ) + 1 AS K ,
        COALESCE(ddmid.equality_columns, '')
        + CASE WHEN ddmid.equality_columns IS NOT NULL
                    AND ddmid.inequality_columns IS NOT NULL THEN ','
               ELSE ''
          END + COALESCE(ddmid.inequality_columns, '') AS Keys ,
        COALESCE(ddmid.included_columns, '') AS [include] ,
        'Create NonClustered Index IX_' + t.name + '_missing_'
        + CAST(ddmid.index_handle AS VARCHAR(20)) 
        + ' On ' + ddmid.[statement] COLLATE database_default
        + ' (' + ISNULL(ddmid.equality_columns, '')
        + CASE WHEN ddmid.equality_columns IS NOT NULL
                    AND ddmid.inequality_columns IS NOT NULL THEN ','
               ELSE ''
          END + ISNULL(ddmid.inequality_columns, '') + ')'
        + ISNULL(' Include (' + ddmid.included_columns + ');', ';')
                                                  AS sql_statement ,
        ddmigs.user_seeks ,
        ddmigs.user_scans ,
        CAST(( ddmigs.user_seeks + ddmigs.user_scans )
        * ddmigs.avg_user_impact AS BIGINT) AS 'est_impact' ,
        avg_user_impact ,
        ddmigs.last_user_seek ,
        ( SELECT    DATEDIFF(Second, create_date, GETDATE()) Seconds
          FROM      sys.databases
          WHERE     name = 'tempdb'
        ) SecondsUptime 
FROM    sys.dm_db_missing_index_groups ddmig
        INNER JOIN sys.dm_db_missing_index_group_stats ddmigs
               ON ddmigs.group_handle = ddmig.index_group_handle
        INNER JOIN sys.dm_db_missing_index_details ddmid
               ON ddmig.index_handle = ddmid.index_handle
        INNER JOIN sys.tables t ON ddmid.OBJECT_ID = t.OBJECT_ID
WHERE   ddmid.database_id = DB_ID()
ORDER BY est_impact DESC;

GO

Внешние ключи

Внешние ключи определяют связь между таблицами и используются для контроля ссылочной целостности. На диаграмме сущность-связь линии между таблицами обозначают внешние ключи.

-- Foreign Keys 

SELECT  @@Servername AS ServerName ,
        DB_NAME() AS DB_Name ,
        parent.name AS 'TableName' ,
        o.name AS 'ForeignKey' ,
        o.[Type] ,
        o.Create_date
FROM    sys.objects o
        INNER JOIN sys.objects parent ON o.parent_object_id = parent.object_id
WHERE   o.[Type] = 'F' -- Foreign Keys 
ORDER BY parent.name ,
        o.name 

--OR 

SELECT  f.name AS ForeignKey ,
        SCHEMA_NAME(f.SCHEMA_ID) AS SchemaName ,
        OBJECT_NAME(f.parent_object_id) AS TableName ,
        COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName ,
        SCHEMA_NAME(o.SCHEMA_ID) ReferenceSchemaName ,
        OBJECT_NAME(f.referenced_object_id) AS ReferenceTableName ,
        COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
                                              AS ReferenceColumnName
FROM    sys.foreign_keys AS f
        INNER JOIN sys.foreign_key_columns AS fc
               ON f.OBJECT_ID = fc.constraint_object_id
        INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id
ORDER BY TableName ,
        ReferenceTableName;

GO

Пропущенные индексы по внешним ключам

Как я уже говорил, желательно иметь индекс, построенный по столбцам, входящим во внешний ключ. Это значительно ускоряет соединения таблиц, которые, обычно, всё равно соединяются по внешнему ключу. Эти индексы так же значительно ускоряют операции удаления. Если такого индекса нет, SQL Server будет производить table scan связанной таблицы, при каждом удалении записи из «первой» таблицы.

-- Foreign Keys missing indexes 
-- Помните, что этот скрипт работает только для создания индексов по одному столбцу
-- Внешние ключи, состоящие более чем из одного столбца, не отслеживаются

SELECT  DB_NAME() AS DBName ,
        rc.Constraint_Name AS FK_Constraint , 
-- rc.Constraint_Catalog AS FK_Database, 
-- rc.Constraint_Schema AS FKSch, 
        ccu.Table_Name AS FK_Table ,
        ccu.Column_Name AS FK_Column ,
        ccu2.Table_Name AS ParentTable ,
        ccu2.Column_Name AS ParentColumn ,
        I.Name AS IndexName ,
        CASE WHEN I.Name IS NULL
             THEN 'IF NOT EXISTS (SELECT * FROM sys.indexes
                                    WHERE object_id = OBJECT_ID(N'''
                  + RC.Constraint_Schema + '.' + ccu.Table_Name
                  + ''') AND name = N''IX_' + ccu.Table_Name + '_'
                  + ccu.Column_Name + ''') '
                  + 'CREATE NONCLUSTERED INDEX IX_' + ccu.Table_Name + '_'
                  + ccu.Column_Name + ' ON ' + rc.Constraint_Schema + '.'
                  + ccu.Table

Email Router for CRM 2011

1)How to verify settings:

– Check the ‘E-Mail Access Configuration’ settings are correct (User administration in CRM)
– That the username and password in the users queue is correct (‘Queue Information -> ‘Configure Credentials for E-Mail Router’
– Log into CRM as the user, go into personal settings (File -> Options -> Email) and make sure the username and password there is correct.

Note: If this fails to work, usually Exchange is having an issue or the email configuration itself needs to be reconfigured to meet any network changes you might have made.

2) E-mail Router Configuration – CRM 2011 Online & Exchange Online

3)  Forwarding Mailbox not working with sent emails from outside CRM

4) how can i configure Email router for MS CRM 2011

5) http://www.interactivewebs.com/blog/index.php/server-tips/crm-2011-email-router-setup-and-settings/

6)  I have come across an issue with emails being processed by the email router, it appears emails with a plus sign (+) in the subject are not getting processed. Has anyone seen this, and/or found a fix?

Set Allow Double Escaping to True on your Exchange Web Site.

The MSDN link for Incoming EMail Config Issues: This is for both the v4.0 and 2011 EMail Routers.

http://msdn.microsoft.com/en-us/library/ee694774.aspx

Instructions: Run the following command on the Exchange Web site to allow double escaping:
%windir%system32inetsrvappcmd set config “Default Web Site” -section:system.webServer/security/requestfiltering -allowDoubleEscaping:true

Here’s an additional support article about the issue: http://support.microsoft.com/kb/2004573

 

7) E-mail Router Configuration – CRM 2011 Online & Exchange Online

September 16, 2011

 The CRM e-mail router is available for implementation with Exchange On-Premise, POP3 accounts, and Exchange Online.  In this article my focus is on implementing the E-mail Router with Exchange Online.

For additional information regarding other available options and supporting resources, please see my article,

CRM Online E-mail Router – Yes We Do That!

So let’s get started.  To begin, you’ll want to ensure you understand the hardware / software requirements.  These were pulled directly from the E-mail Router Installation Guide:

  • Windows 7, Windows Server 2008

Next, you’ll want to consider a few configuration options and make decisions:

  • How do you want to handle Incoming mail for each user?
  • How do you want to setup the Outgoing Mail Profile?

Incoming Mail Options

You have a couple of options regarding the Incoming Mail Profile; do you want to have the e-mail router handle both outgoing and incoming or do you want to use the Forward Mailbox for Incoming.  The benefit for using the Forward Mailbox is that you have only one point of failure to troubleshoot incoming mail issues, the Forward Mailbox.  If each user is configured to use the E-mail Router to manage incoming e-mail then you might have to troubleshoot issues at the Outlook user mailbox level.  The downside to this approach for some is it requires an additional mailbox setup for the Forward Mailbox and Rule Deployment to manage the forwarding mail process.  The upside is that it scales well as organizations grow.

Additionally, you’ll need to decide if you are going to setup one Incoming profile for each user or use one Incoming Profile for all.  The most common approach is to use one Incoming Profile for all users.  If that is the choice you make then the Access Credentials you choose to use for this profile must have full access to all user mailboxes.  If you choose to setup one Incoming Profile for each user then you will need to know the Exchange Online password for each user.

Outgoing Mail Options

The option you want to focus on for the Outgoing Mail Profile is do you want to use an Administrator level account for Access or setup each user account.  Generally, you’ll want to use an Administrator level account for Access rather than setting up individual Outgoing profiles.  An Administrator level account assumes full rights to all user’s mailboxes.  There will be some important items to pay close attention to when setting up this configuration to include a required call to Exchange Online support to complete a few configuration steps which I’ll highlight later in the article.

After you’ve identified the best configuration options for your organization and completed the preparation work required for the options you selected, you are ready to install the e-mail router.

E-mail Router Installation

One of the best resources I’ve found for a detailed guide on installing the E-mail Router for CRM Online and Exchange Online is the article written a few years ago on the Dynamics CRM Team Blog,

Configure Microsoft Dynamics CRM Online E-mail Router with Exchange Online

Although some of this will be a repeat of the above article, the following steps are from a ‘real-world’ installation, so here we go:

 

First, ensure your CRM users have been configured to use the E-mail Router.

  • Go to CRM Online, select Settings, Administration, Users, select each User and update the E-mail Access Type Incoming and Outgoing fields under the Email Configuration section.
  • Also ensure  you’ve that you’ve selected the Approve E-mail button from the Ribbon.

UserImage

Now we are ready to install and test the E-mail Router

  • Download the CRM 2011 E-mail Router and run the installation package.  You can choose from a 32 or 64 bit package depending on your machine setup.
  • Select to Install any prerequisites required

image

  • If you received the error message, the Microsoft Exchange Server MAPI subsystem is not installed on this system, please see this KB article for the fix

image

  • If you needed to apply the fix, select back once the fix is applied and select next.  If no errors were encountered, select finish if the installation completed successfully.  If the installation did not complete successfully, you need to resolve all error before proceeding.

image

  • Next you’ll go to Start Programs, Microsoft Dynamics CRM 2011 E-mail Router and open the Configuration Manager

image

  • Remaining on the Configuration Profile tab, we’ll create the Incoming and Outgoing profile.  You may not need both depending on how you plan to use the e-mail router.

Outgoing Profile

  • Enter a Profile Name, Select Outgoing for the Direction and Select Exchange Online from the E-mail Server Type
  • Enter the Exchange Online Web Server URL which can be found in the Configure Microsoft Dynamics CRM Online E-mail Router with Exchange Online article and documentation.
  • Select Other Specified for the Access Credential, select Administrator for the User Type and enter the credentials of an Exchange Online Administrator account
  • For Access Type, select the desired option.
    • Note: the difference between Delegate Access and Send as Permission is Delegate Access causes e-mail to display “Sent on behalf of (specified CRM User)” and Send as Permission causes the e-mail to appear as though it was sent directly by the CRM User
    • Note:from the documentation: “The Send As setting is currently not enabled by default for the Exchange Online Administrator. Please call Exchange Online Support to update the setting.  This may change with future releases”image

Incoming Profile

  • Enter a Profile Name, Select Incoming for the Direction and Select Exchange Online from the E-mail Server Type
  • Enter the Exchange Online Web Server URL which can be found in the Configure Microsoft Dynamics CRM Online E-mail Router with Exchange Online article and documentation.
  • Select Other Specified for the Access Credential, select Administrator for the User Type and enter the credentials of an Exchange Online Administrator account

IncomingProfile

Deployment Profile

  • Select the Deployments Tab and select the New button from the right navigation menu

image

  • Select Microsoft Dynamics CRM Online and replace <OrganizationName> with Your Unique Org name.
    • You can find your CRM Online Unique Org Name by going to Settings, Customization, Developer Resources and copy the value found under the first entry, “Organization Unique Name”
    • Do not replace the first part of the URL “https://dev.CRM.dynamics.com/”  only replace this value <OrganizationName> with your unique organization name

image

OrgUniqueName

  • Enter the Live ID in the User Name and related password that is used by a CRM User with the System Administration role to login into CRM Online.  The user name should be in the same format as that used to log into CRM, crmuser@domain.com
  • Select the Incoming and Outgoing profile for each of the applicable Default configuration profiles

deploymentProfile

  • Select Ok and select the Publish button in the lower right-hand corner of the Window

Test the E-mail Router

  • Go to the Users, Queues and Forward Mailbox tab and select the Load Data tab.
  • If all configurations are correct to include passwords,  you should see a list of your CRM users when the action is completed.
  • Once the Users are loaded you can select the Test Access button from the right navigation menu

image

Forward Mailbox

If you plan to use the Forward Mailbox to manage incoming mail, select the Forward Mailbox tab and select the New button.  Enter a Name for the forward mailbox, enter the mailbox address for the forward mailbox and select Incoming.

ForwardMailbox

  • If you choose to use a Forward mailbox, you’ll need to change each User record in CRM to Forward Mailbox for Incoming Configuration and Deploy the Forward Mailbox rule.

E-mail Router Service

In closing, the E-mail Router Service plays an important role in ensuring the everything works as expected.  Therefore, it is important that you set the logon for the E-mail Router service to a logon that has sufficient rights.  To do this, ensure that the user account that is running the E-mail Router Service is a member of the Active Directory directory service PrivUserGroup security group.

I hope you found this article helpful.

SharePoint Administration ….

1) SharePoint Administration Kit from Axceler

by Marcello Tonarelli 

Both Microsoft SharePoint administration and SharePoint governance are growing concerns in many organizations

2) SharePoint Performance Monitor v2.0

3)Free SharePoint Health Monitor Tool 

4) Out of the box Functionality of SharePoint 2010 

5) Microsoft Dynamics CRM integration with SharePoint Online is here 

6) SharePoint Site Collection Lock and Unlocking 

7) SharePoint Search service is in Starting or Stopping state ? 

8)

8 Most Used Feature in SharePoint

1.            Corporate Directory

SharePoint Developers have integrated a corporate directory feature that will serve as an electronic file for a company. Having this feature eliminates the tedious process of looking at every file stored in the file cabinet

Corporate Directories can be helpful in looking for certain information about an employee It can also allow a user to search for profiles on a last name or first name basis making information accessibility easier. Also, it just takes seconds to a minute to display all searches in a printable format.

2.            HR policies, Corporate Information, Guidelines

Corporate Information, policies and other guidelines are being studied by the newly hired employee to be able to have a harmonious working relationship with other employee. This is one of the many reason why company information is shared on the intranet Since in most organization the guidelines are created by higher authority, information dissemination is important for the guidelines to be implemented. It can also include rules, norms, the company’s success or undertakings and other work related information that will be useful and needs to be known to the employees.

3.            Status Updates (microblogging)

Similar to the social blogging function, microblogging in SharePoint is intended to express the ideas and feelings of an individual. It can be in the form of a status update, which will be shown not only on the profile page of the user but also to other employees that are connected to that user. This feature is commonly used because it allows people within the organization to communicate and collaborate in real time speed. Other employees who are also concerned with that topic can read your post.

The difference between microblogging in SharePoint and those available in social networking sites is that you can have security in your blog. Ensuring that only people from your organization can read the blogs posted. Keeping organization related data circulating within the company and not on the entire web.  It is private in the sense that it is intended to be used within the organization but at the same time public since other employees within the organization can read your post. Similar to social networking sites, this feature will enable you to look-up your co-worker’s specific information like birthday, notes and status updates.

4.            Specific Application

The advantage of using SharePoint in your organization is that you can easily create a custom solution or an application that will address a specific need, and can be modified afterwards. This also include data/information within an organization that are in the form of databases For example, if there is a need to configure the outgoing portion of your e-mail setting you can freely do so. There are numerous ways for this to be done But usually it would need help from experts to be able to carry on creating this application.

5.            File sharing

If your organization is running for years now, then you must have tons of files about past projects, documents, contracts and other things. There is a difficulty in organizing and tracking files since they are located on different areas

Using File sharing that is readily available when using SharePoint can help you organize information, making it easier to access for future use. Instead of having many folders that contains revisions and other versions on a certain document, you will be able to have only one updated version of that document making it available to whoever will be needing it on time. Other benefits of File Sharing would be the comfort of sending links to employees rather than attaching files one by one. It is also a fast and easy way to find documents and organizing files.

6.            Employee Forum

The employee forum can also be called as a discussion forum which by default has one discussion board available. Discussion board can be customized Forum allows the most recent topic discussed to be shown to the employee This helps the company have a general idea on their employee’s thoughts. It also serves as a central information source for employees.

7.            Calendar sharing

Calendar sharing is commonly used by large teams in organizing their project schedules, deadlines, leaves and vacations in order to check and avoid conflicts with other events that are already planned for the organization.

You can be able to see more than one calendar at a time. SharePoint offers the option to view your calendar together with other outlook calendars you have.

8.            General Search

Many organizations do not give much attention to the general search function that is available even in the free version of SharePoint. General search helps you locate information when you already have a specific scope in mind It can also help you do searches on business documents, templates, guidelines, polices and others that are stored within the libraries of the organization. When you modify SharePoint you can also have the PDF files indexed which will be easier to read.

9) What is SharePoint 2010 14 hive directory?

Following are some of the folders in the “14 hive” directory:

  1. Program Files\Common files\Microsoft Shared\Web Server Extensions\14 – This directory is the installation directory for core SharePoint Server files.
  2. Program Files\Common files\Microsoft Shared\Web Server Extensions\14\ADMISAPI – This directory contains the SOAP services for Central Administration. If this directory is altered, remote site creation and other methods exposed in the service will not function correctly.
  3. Program Files\Common files\Microsoft Shared\Web Server Extensions\14\CONFIG – This directory contains files used to extend IIS Web sites with SharePoint Server. If this directory or its contents are altered, Web application provisioning will not function correctly.
  4. Program Files\Common files\Microsoft Shared\Web Server Extensions\14\LOGS – This directory contains setup and run-time tracing logs.

Following are some new folders added in the “14 hive” directory:

  1. Program Files\Common files\Microsoft Shared\Web Server Extensions\Policy
  2. Program Files\Common files\Microsoft Shared\Web Server Extensions\UserCode – This directory contains files used to support your sandboxed solutions.
  3. Program Files\Common files\Microsoft Shared\Web Server Extensions\WebClients – This directory contains files related to the new Client Object Model.
  4. Program Files\Common files\Microsoft Shared\Web Server Extensions\WebServices – This directory contains new WCF or .svc related files

9. Plan alternate access mappings (Windows SharePoint Services)

10. InfoPath form library forms cannot be filled out in a Web browser

Resolution:

  1. Open the central Administration
  2. Application management
  3. Service applications
  4. Configure service application associations
  5. Select the web application for whim it’s failing
  6. Click on custom
  7. It will open the service application options
  8. Select the state service check box and click OK

Once you are done with the above steps then come back to health analyzer list, click on the same rule and hit “Reanalyze now” – that’s it, you are done.

– See more at: http://sharepointknowledgebase.blogspot.in/2014/04/infopath-form-library-forms-cannot-be.html

Migrate CRM SQL 2005 32 bit to SQL 2008 64 bit Environment

Source – http://edwardsdna.wordpress.com/2011/06/07/migratecrm/

Перенос образов из Hyper-V в VirtualBox

by Артем Enot Грунин

2)Oracle VM VirtualBox

By Marcello Tonarelli

The latest release is version 4.0.4.

On this page you can download:

Previous Older Entries