[SQL]從sql server取得AD資訊

[SQL]從sql server取得AD資訊

最近有需求要取得AD最後密碼修改日期

紀錄一下過程

 

STEP 1: 設定linked server

-- http://technet.microsoft.com/zh-tw/library/ms190479.aspx
-- http://www.sqlservercentral.com/Forums/Topic259587-8-2.aspx
-- http://tsuozoe.pixnet.net/blog/post/22419129-sp_addlinkedsrvlogin-%E3%80%81-sp_droplinkedsrvlogin-%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95-
use master 
go
 
 
--增加linked server
--設定linked server登入身分
 
/****** 物件:  LinkedServer [ADSI]    指令碼日期: 12/18/2008 13:43:56 ******/
EXEC master.dbo.sp_addlinkedserver @server = N'ADSI', @srvproduct=N'Active Directory Services', @provider=N'ADSDSOObject', @datasrc=N'adsdatasource'
/* For security reasons the linked server remote logins password is changed with ######## */
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'ADSI',@useself=N'False',@locallogin=NULL,@rmtuser=N'account',@rmtpassword='password'
 
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'collation compatible', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'data access', @optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'dist', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'pub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'rpc', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'rpc out', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'sub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'connect timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'collation name', @optvalue=null
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'lazy schema validation', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'query timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'ADSI', @optname=N'use remote collation', @optvalue=N'true'
 
 
 
--刪除linked server
 
EXEC sp_droplinkedsrvlogin 'ADSI', NULL
sp_dropserver 'ADSI'
 
--查詢server列表
select * from sys.servers

 

STEP 2:開始跟AD查詢資料

-- http://www.codeproject.com/Articles/37094/Building-a-Hybrid-Active-Directory-and-SQL-Table-D#
-- http://www.sqlservercentral.com/Forums/Topic259587-8-1.aspx
-- http://www.myitforum.com/forums/SCCM-WQL-Query-PwdLastSet-m233388.aspx
-- http://www.sqlteam.com/forums/topic.asp?topic_id=108759
-- http://www.dotblogs.com.tw/angi/archive/2008/11/26/6085.aspx
-- http://www.blueshop.com.tw/board/show.asp?subcde=BRD201003101620505Z5
 
use test_db 
go
 
 
 
--預設情況下,SQL Server不允許 OpenQuery,所以用 show advanced option 打開系統預儲程式進階選項並配合下面的 Ad Hoc Distributed Queries 選項   
sp_configure 'show advanced options', 1   
reconfigure with override   
 
--再使用 Ad Hoc Distributed Queries 打開特定分散式查詢選項   
sp_configure 'Ad Hoc Distributed Queries', 1   
reconfigure   
 
 
 
 
--  要處理時間轉換
 
--  1. 將pwdLastset從長整數轉換為日期
--  法一:
--  cast((cast(pwdLastSet as numeric)/ 864000000000.0 - 109207) AS DATETIME)
--  法二:
--  DECLARE    @SourceValue BIGINT
--  SELECT    @SourceValue = 129145609981852500
--  SELECT    @SourceValue = (@SourceValue - 47966688000000000) / 600000000.0
--  SELECT    DATEADD(MINUTE, @SourceValue, '17530101')
 
--  2. 將轉換後的時間轉為本地時間(UTC to LOCAL)
--  DECLARE @LocalDate DATETIME,@UTCDate DATETIME,@LocalDate2 DATETIME 
--  SET @LocalDate = GETDATE()
--  SET @UTCDate = DATEADD(hour, DATEDIFF(hour,GETDATE(),GETUTCDATE()), @LocalDate);
--  SET @LocalDate2 = DATEADD(hour, DATEDIFF(hour,GETUTCDATE(),GETDATE()), @UTCDate);
--  print @LocalDate
--  print @UTCDate
--  print @LocalDate2
 
-- 查詢AD 狀態(法一 :增加Link Server後,使用OPENQUERY)
declare @USRID varchar(6)
set @USRID='123456';
 
select cn,  samAccountName ,
case when pwdLastSet ='0' then null
else DATEADD(hour, DATEDIFF(hour,GETUTCDATE(),GETDATE()) ,cast((cast(pwdLastSet as numeric)/ 864000000000.0 - 109207) AS DATETIME) )
end as pwdLastSetDate 
from
(SELECT  cn,  samAccountName , pwdLastSet
 
FROM OPENQUERY(ADSI, 
 
'SELECT samAccountName, pwdLastSet, cn
 
FROM ''LDAP://test.com'' where objectCategory = ''Person'' and objectClass = ''User'' ') 
 
AS a 
inner join test_db..EMPLOYEE as b on a.cn collate Chinese_Taiwan_Stroke_BIN = b.STAFF
where b.STATUS=1
) c  where cn=@USRID  ORDER BY cn 
 
 
-- 查詢AD 狀態(法二 :使用OPENROWSET)
declare @USRID varchar(6)
set @USRID='123456';
 
select cn,  samAccountName ,
case when pwdLastSet ='0' then null
else DATEADD(hour, DATEDIFF(hour,GETUTCDATE(),GETDATE()) ,cast((cast(pwdLastSet as numeric)/ 864000000000.0 - 109207) AS DATETIME) )
end as pwdLastSetDate 
from
(SELECT  cn,  samAccountName , pwdLastSet
 
FROM OPENROWSET('ADSDSOObject', 'adsdatasource;', 
 
'SELECT samAccountName, pwdLastSet, cn
 
FROM ''LDAP://test.com'' where objectCategory = ''Person'' and objectClass = ''User'' ') 
 
AS a 
inner join test_db..EMPLOYEE as b on a.cn collate Chinese_Taiwan_Stroke_BIN = b.STAFF
where b.STATUS=1
) c  where cn=@USRID  ORDER BY cn 


備註

如果OPENQUERY不能使用請參照下列步驟

-- http://hoolihome.blogspot.com/2010/10/test-sqlncli.html
-- sp_serveroption : http://technet.microsoft.com/zh-tw/library/ms178532.aspx
-- sp_addlinkedserver : http://technet.microsoft.com/zh-tw/library/ms190479.aspx
-- OPENQUERY : http://technet.microsoft.com/zh-tw/library/ms188427.aspx
use master
go
 
--預設data access為false
exec sp_serveroption 'INDBT1','data access',false
 
 
SELECT * FROM OPENQUERY (INDBT1, 'SELECT * FROM
testdb.dbo.test1') 
 
--解決方式 : 將data access打開
exec sp_serveroption 'INDBT1','data access',true 
 
--正常顯示
SELECT * FROM OPENQUERY (INDBT1, 'SELECT * FROM
testdb.dbo.test1')