dynamic sql - assigning variable a value from result of dynamic sql query
You were missing the variable assignment inside the dynamic SQL batch.

DECLARE @sqlcommand NVARCHAR(MAX) = 'SELECT TOP 1 @ID = (ID) --Assign me!
                                     FROM ' + QUOTENAME(@tablename) + ' 
                                     WHERE LastModified &lt; DATEADD(DAY,' + @NumberOfKeepDays + ', GETDATE()) 
                                    ORDER BY 1 DESC';

EXECUTE sys.sp_executesql @sqlcommand, N'@ID BIGINT OUTPUT', @ID = @ID OUTPUT;


The example from the sp_executesql doc is pretty clear, though suffers from formatting.

DECLARE @SQLString nvarchar(500);  
DECLARE @ParmDefinition nvarchar(500);  
DECLARE @SalesOrderNumber nvarchar(25);  
DECLARE @IntVariable int;  

SET @SQLString = N'SELECT @SalesOrderOUT = MAX(SalesOrderNumber) --Assign me!
    FROM Sales.SalesOrderHeader  
    WHERE CustomerID = @CustomerID';  
SET @ParmDefinition = N'@CustomerID int,  
    @SalesOrderOUT nvarchar(25) OUTPUT';  
SET @IntVariable = 22276;  

EXECUTE sp_executesql  
    @SQLString  
    ,@ParmDefinition  
    ,@CustomerID = @IntVariable  
    ,@SalesOrderOUT = @SalesOrderNumber OUTPUT;  
-- This SELECT statement returns the value of the OUTPUT parameter.  
SELECT @SalesOrderNumber; 


If you want to learn a whole heck of a lot about dynamic SQL, SQL injection (and you should, because what you're executing now is potentially unsafe), head over here