For something like this, I like to use either a numbers/tally table or function. In this case, I'll use a function called tfn_Tally (I'll post the function code below the answer)...
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
DROP TABLE #TestData;
GO
CREATE TABLE #TestData (
CourseID CHAR(4) NOT NULL,
CourseTitle VARCHAR(20) NOT NULL,
BegDate DATE NOT NULL,
EndDate DATE NOT NULL
);
INSERT #TestData (CourseID, CourseTitle, BegDate, EndDate) VALUES
('M001', 'Math', '1/1/2017', '01/20/2017'),
('M002', 'Aljabar', '2/2/2017', '02/20/2017'),
('E001', 'Conversation', '1/3/2017', '01/25/2017'),
('E002', 'Vocabs', '1/3/2017', '02/20/2017');
--=========================================================
SELECT
td.CourseID,
td.CourseTitle,
TheDate = DATEADD(dd, t.n, td.BegDate)
FROM
#TestData td
CROSS APPLY dbo.tfn_Tally(DATEDIFF(dd, td.BegDate, td.EndDate) + 1, 0) t;
Code for tfn_Tally...
CREATE FUNCTION dbo.tfn_Tally
/* ============================================================================
07/20/2017 JL, Created. Capable of creating a sequense of rows
ranging from -10,000,000,000,000,000 to 10,000,000,000,000,000
============================================================================ */
(
@NumOfRows BIGINT,
@StartWith BIGINT
)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
WITH
cte_n1 (n) AS (SELECT 1 FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (n)), -- 10 rows
cte_n2 (n) AS (SELECT 1 FROM cte_n1 a CROSS JOIN cte_n1 b), -- 100 rows
cte_n3 (n) AS (SELECT 1 FROM cte_n2 a CROSS JOIN cte_n2 b), -- 10,000 rows
cte_n4 (n) AS (SELECT 1 FROM cte_n3 a CROSS JOIN cte_n3 b), -- 100,000,000 rows
cte_Tally (n) AS (
SELECT TOP (@NumOfRows)
(ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1) + @StartWith
FROM
cte_n4 a CROSS JOIN cte_n4 b -- 10,000,000,000,000,000 rows
)
SELECT
t.n
FROM
cte_Tally t;
GO