Theo's helpful answer addresses incidental logic problems with your approach and offers a solution that probably will work, but isn't fully robust: If the activity in your loop exceeds 1 minute before the timeout condition is tested, the test won't work as intended (even with the logic problems fixed).
You have two options:
Use .TotalSeconds instead of .Seconds, for the reasons explained below.
More simply, taking advantage of the fact that [timespan] instances are directly comparable (see below), you can use:
if ($stopwatch.elapsed -gt $timeout) { # ...
As zett42 points out, [timespan] instances are directly comparable, due to implementing the .NET System.IComparable interface (as well as its generic counterpart); e.g.:
# -> $true - a timespan representing a 61-second duration
# is greater than one representing a 60-second (1-minute) duration.
[timespan]::FromSeconds(61) -gt [timespan] '00:01:00'
Therefore, as shown in the top section, you can simply directly compare $stopwatch.elapsed and $timeout - both of which are [timespan] instances.
The .Seconds property of a [timespan] instance is only the seconds component, potentially alongside larger units, such as minutes (.Minutes) and hours (.Hours)
You need the .TotalSeconds property to get the total amount of seconds (analogously, there are also .TotalDays, .TotalHours, and .TotalMinutes properties).
Also note that .Seconds is always a whole number ([int]), whereas .TotalSeconds can be a fractional value ([double]).
To illustrate the difference:
PS> [timespan] '00:01:05' | # 1 minute and 5 seconds
Select-Object Seconds, TotalSeconds
Seconds TotalSeconds
------- ------------
5 65