The win ensured the African side won Group F and they will face the runners-up of Group E on Tuesday.
Chelsea winger Ziyech pounced on a mistake by Canadian goalkeeper Milan Borjan to give his side the lead, before En-Nesyri fired in 19 minutes later.
An own goal by Nayef Aguerd at the end of the first-half brought Canada back into the game, but the Moroccan’s saw out the second-half to seal their passage through to the next round.
Story of the match
Walid Regragui made two changes to the Morocco side that beat Belgium last time out.
Goalkeeper Yassine Bounou returned to the starting 11 and former Huddersfield winger Abdelhamid Sabiri was also rewarded with a start.
Ritchie Laryea and Stephen Eustaquio were also benched with Junior Hoilett, Jonathan Osorio, Mark-Anthony Kaye and Sam Adekugbe coming into the side.
Morocco’s start couldn’t have been any better, as they took the lead in the fourth minute when Ziyech pounced on a heavy touch by Canadian keeper Borjan.
Rather than clearing his lines, Borjan tried to dribble out of his box and the 29-year-old lofted the ball excellently into the empty net.
Canada almost equalised 11 minutes later, as Cyle Larin burst down the right-hand side but his cross was agonisingly too far in front of Tajon Buchanan.
But it was Sevilla striker En-Nesyri who made it 2-0 on 23 minutes, when he ran in behind the Canadian back-line, before firing low past Borjan.
The Atlas Lions were looking very bright and it took a fine block by Canadian right-back Alistair Johnston to prevent it from becoming 3-0.
Achraf Hakimi’s fine work on the right side resulted in the ball falling to Sabiri, but his shot was excellently blocked by Johnston in the nick of time.
It was Canada though, who managed to find the net at the end of the half, slightly against the run of play.
Adekugbe lashed the ball across the face of goal and an unfortunate Nayef Aguerd diverted the ball into his own net for the first own-goal of the tournament.
Morocco almost responded immediately but En-Nesyri’s fine volley was ruled out after Aguerd was adjudged to be offside and in the Canadian keeper’s eye-line.
Alphonso Davies is without a doubt the star of the Canada side and he had the first clear opportunity of the second period.
Hoilett found the Bayern Munich man in the box, but he could only hit his shot wide of the post.
Shortly after, Canada boss John Herdman rang the changes with Hutchinson, David and Ismael Kone all coming onto the field in an attempt to grab the North-Americans their first point of the tournament.
The Moroccans were sensing a place in the knockout stages of the World Cup and they made a couple of substitutions themselves.
Zakaria Aboukhlal and Selim Amallah replaced Sofiane Boufal and Sabiri for the North-Africans.
But it was one of the Canadian changes that almost made an instant impact.
The 39-year-old Hutchinson met a corner for the Maple Leafs, but his header crashed against the crossbar and dropped down onto the line before it was cleared away from danger.
With 15 minutes remaining, both managers decided to make further substitutions as the game reached its final stages.
David Wotherspoon replaced Hoilett for Canada, while Morocco brought on Abderrazak Hamdallah and Jawad El Yamiq for Azzedine Ounahi and Ziyech.
Morocco saw out the rest of the match and their attention will now turn to the knockout stages.
It’s the end of the World Cup journey for Canada, but their performances have really captured the imagination in Qatar and there are promising signs for the Maple Leafs.
They co-host the tournament in 2026 and there is a lot to work with for a nation who were only participating in their second ever World Cup.
Player of the Match – Hakim Ziyech
The Chelsea man was a constant threat throughout and he scored early on to get his nation off to the best possible start.
He anticipated a poor error by the Canadian goalkeeper before delivering an exquisite chip to set the Atlas Lions on their way.
If Morocco are to go on a run in the knockout stages, then the 29-year-old will be a key man.