See article http://www.simple-talk.com/sql/sql-server-2005/sql-server-2005-ddl-TRIGGER-workbench/ which describes 
SQL Server 2005 DDL Triggers.
I have implemented these with some amendments:- 


CREATE TABLE [dbo].[DDLChangeLog](
   
[DatabaseName] [nvarchar](50) NOT NULL CONSTRAINT [DF_ddl_log_DatabaseName]  DEFAULT (DB_NAME()),
   
[DDLChangeLog_ID] [int] IDENTITY(1,1) NOT NULL,
   
[InsertionDate] [datetime] NOT NULL CONSTRAINT [DF_ddl_log_InsertionDate]  DEFAULT (GETDATE()),
   
[CurrentUser] [nvarchar](50) NOT NULL CONSTRAINT [DF_ddl_log_CurrentUser]  DEFAULT (CONVERT([nvarchar](50),USER_NAME(),(0))),
   
[LoginName] [nvarchar](50) NOT NULL CONSTRAINT [DF_DDLChangeLog_LoginName]  DEFAULT (CONVERT([nvarchar](50),SUSER_SNAME(),(0))),
   
[Username] [nvarchar](50) NOT NULL CONSTRAINT [DF_DDLChangeLog_Username]  DEFAULT (CONVERT([nvarchar](50),original_login(),(0))),
   
[EventType] [nvarchar](100) NULL,
   
[objectName] [nvarchar](100) NULL,
   
[objectType] [nvarchar](100) NULL,
   
[tsql] [nvarchar](MAX) NULL,
 
CONSTRAINT [PK_DDLChangeLog] PRIMARY KEY CLUSTERED  (
   
[DDLChangeLog_ID] ASC )WITH (PAD_INDEX  = OFFSTATISTICS_NORECOMPUTE  = OFFIGNORE_DUP_KEY = OFFALLOW_ROW_LOCKS  = ONALLOW_PAGE_LOCKS  = ONON [PRIMARY] ON [PRIMARY]

GO SET ANSI_PADDING OFF GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'The Database where the trigger was fired' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'DDLChangeLog'@level2type=N'COLUMN',@level2name=N'DatabaseName' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'Reference' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'DDLChangeLog'@level2type=N'COLUMN',@level2name=N'DDLChangeLog_ID' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'Time the trigger was fired' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'DDLChangeLog'@level2type=N'COLUMN',@level2name=N'InsertionDate' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'User running the change' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'DDLChangeLog'@level2type=N'COLUMN',@level2name=N'CurrentUser' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'Logged in User' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'DDLChangeLog'@level2type=N'COLUMN',@level2name=N'LoginName' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'Originally logged in as' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'DDLChangeLog'@level2type=N'COLUMN',@level2name=N'Username' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'Event action' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'DDLChangeLog'@level2type=N'COLUMN',@level2name=N'EventType' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'Object name' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'DDLChangeLog'@level2type=N'COLUMN',@level2name=N'objectName' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'Object Type' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'DDLChangeLog'@level2type=N'COLUMN',@level2name=N'objectType' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'Code applied' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'DDLChangeLog'@level2type=N'COLUMN',@level2name=N'tsql' GO
I have implemented on all databases on my server to do this run the results of the following
script this will add a DDL trigger to all databases on a server. Note that when the trigger
fires it will be populating the [Servername].[dbo].[DDLChangeLog] table. The table/database
name should be changed so you are recording into a central database.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SET 
LOCK_TIMEOUT 10000 SET FMTONLY OFF
SET 
NOCOUNT ON
IF  EXISTS (SELECT FROM sys.objects WHERE OBJECT_ID OBJECT_ID(N'#temp') AND type IN (N'U')) DROP TABLE #temp GO
CREATE TABLE #Temp (ID INT IDENTITY (1,1), DatabaseName VARCHAR (150))
DECLARE  @Counter INT
   
,@Maxcount INT
   
,@DatabaseName VARCHAR(150)
   ,
@SQL VARCHAR(1000)


   
INSERT INTO #Temp
   
(DatabaseName)
   
SELECT [name] AS DatabaseName 
   
FROM master.dbo.sysdatabases
   
WHERE [name] NOT IN ('msdb','temp')

   
SET @Counter 1
   
SET @Maxcount =  (SELECT MAX(idFROM #Temp)

   
WHILE @Counter <= @maxcount
   
BEGIN
   SET 
@DatabaseName (SELECT DatabaseName 
                   
FROM #Temp 
                   
WHERE ID @Counter)

   
SET @SQL 'USE '+@DatabaseName CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +' GO 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'CREATE TRIGGER trgLogDDLEvent_'+@DatabaseName+' ON DATABASE 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'FOR DDL_DATABASE_LEVEL_EVENTS '+CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'AS 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'DECLARE @data XML 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'SET @data = EVENTDATA() 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'    IF @data.value(''(/EVENT_INSTANCE/EventType)[1]'', ''nvarchar(100)'') 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'        <> ''CREATE_STATISTICS''  'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'       INSERT  INTO [Servername].[dbo].[DDLChangeLog] 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                ( EventType, 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                  ObjectName,' CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                  ObjectType,' CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                  tsql 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                ) 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'        VALUES  ( 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                  @data.value(''(/EVENT_INSTANCE/EventType)[1]'', 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                              ''nvarchar(100)''), 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                  @data.value(''(/EVENT_INSTANCE/ObjectName)[1]'', 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                              ''nvarchar(100)''), 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                  @data.value(''(/EVENT_INSTANCE/ObjectType)[1]'', ' CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                              ''nvarchar(100)''), ' CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                  @data.value(''(/EVENT_INSTANCE/TSQLCommand)[1]'', 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                              ''nvarchar(max)'') 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'                ) ; 'CHAR(13) + CHAR(10)
   
SET @SQL =  @SQL +'GO 'CHAR(13) + CHAR(10)
PRINT @SQL

   
SET @Counter @Counter+1
   
END

DROP TABLE 
#Temp

To help with housekeeping I have created a archiving routine, to ensure that the growth
of the DDLChangeLog stays manageable. Initially I have populated it with 10 years.
Therefore data in this archive table will be kept for 10 years. The value can be easily changed.

CREATE TABLE [dbo].[Retain](
   
[RetainPeriod] [char](1) NOT NULL,
   
[RetainValue] [int] NOT NULL,
   
[Notes] [varchar](50) NULL,
 
CONSTRAINT [PK_Retain] PRIMARY KEY CLUSTERED  (
   
[RetainPeriod] ASC,
   
[RetainValue] ASC )WITH (PAD_INDEX  = OFFSTATISTICS_NORECOMPUTE  = OFFIGNORE_DUP_KEY = OFFALLOW_ROW_LOCKS  = ONALLOW_PAGE_LOCKS  = ONON [PRIMARY] ON [PRIMARY]

GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'Enter with Y,M or D for year, month or Day' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'Retain'@level2type=N'COLUMN',@level2name=N'RetainPeriod' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'Number of Years, Months or Days to retain daya for.' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'Retain'@level2type=N'COLUMN',@level2name=N'RetainValue' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description'@value=N'Enter notes' @level0type=N'SCHEMA',@level0name=N'dbo'@level1type=N'TABLE',@level1name=N'Retain'@level2type=N'COLUMN',@level2name=N'Notes' GO ALTER TABLE [dbo].[Retain]  WITH CHECK ADD  CONSTRAINT [CK_Retain] CHECK  (([RetainPeriod]='D' OR [RetainPeriod]='M' OR [RetainPeriod]='Y')) GO ALTER TABLE [dbo].[Retain] CHECK CONSTRAINT [CK_Retain]

Populate the Retain 
TABLE

Decide how long you want to keep the information for and  populate the Retain table, the following example will ensure that the data is kept for 10 years, you may want to alter this number.

VALUES acceptable Y,OR FOR yearsmonths OR days.
INSERT INTO [Cumbria].[dbo].[Retain]
           
([RetainPeriod]
           
,[RetainValue]
           
,[Notes])
     
VALUES
           
('Y'
           
,10
           
,'Retains data for 10 years')

Schedule a  job to run the following code at regular intervals to delete the file based on values in the retain table:-

DECLARE @RetainValue INT,
     
@RetainDate 
DATETIME
SET @RetainValue (SELECT MAX(RetainValue

           
FROM {database}.dbo.Retain
)
SET @RetainDate (
SELECT  
   
CASE 
RetainPeriod
      
WHEN 'Y' THEN DATEADD(YEAR,-@RetainValueGETDATE
())
      
WHEN 'M' THEN DATEADD(MONTH,-@RetainValueGETDATE
())
      
WHEN 'D' THEN DATEADD(DAY,-@RetainValueGETDATE
())
      
ELSE DATEADD(YEAR,100,GETDATE
())
   
END AS 
RetainDate FROM {database}.dbo.Retain)
DELETE FROM 
{database}.[dbo].[DDLChangeLog]
    
WHERE InsertionDate <= @RetainDate