Normalize video filenames and move files to destination directory
Get-ChildItem -include *.ext1, *.ext2 instead of Where
Use pipelining via | (in direct fashion, that is without storing the results in intermediate variables) instead of foreach statement so that the processing starts immediately without waiting for the entire directory to be enumerated first (or use the advanced method of non-blocking IO.DirectoryInfo enumeration in a foreach statement).
Join-Path 'dir' * to construct the path for Get-ChildItem instead of relying on the trailing backslash
-LiteralPath instead of -Path, otherwise PowerShell will fail on paths that contain square brackets as it treats [] as a wildcard specifier.
string concatenation instead of switch


And my personal preferences:


Use regex to split the file name - it'll make the structure more obvious (if you know regex)
Use mkdir instead of New-Item -ItemType Directory (I think it's overly verbose to the point of being obfuscatingly so)
Simply create the directory without checking its existence: the operating system does it anyway, and the code is less "noisy" this way.




$fileDirectory = "C:\Test"
$ParentDir = "c:\TV Shows"

Join-Path $fileDirectory * | Get-ChildItem -include *.mkv, *.avi, *.mp4 | ForEach {
    if ($_.BaseName -notmatch '^\s*(.*?)\s*\.S(\d\d)E(\d\d)') {
        return
        # return is used because we're in a function-like ScriptBlock context
    }
    $ShowDir = Join-Path $ParentDir ($matches[1])
    $SeasonDir = Join-Path $ShowDir ('Season ' + $matches[2])
    # $matches is an internal object set automatically by -match or -notmatch operator

    mkdir $ShowDir -Force &gt;$null
    mkdir $SeasonDir -Force &gt;$null
    # mkdir outputs the directory object so we ignore it

    Move -LiteralPath $_.FullName -Destination $SeasonDir
}