function Invoke-DOSCommand {
<#
.SYNOPSIS
Run a DOS command on a remote host and return results
.DESCRIPTION
Invoke-DOSCommand will run a dos command on a remote system and will return the results.
It does this using WMI to create a process and by creating a temporary file on the remote
to store the results if any
.EXAMPLE
Invoke-DOSCommand -Command "netstat -ano"

DESCRIPTION
-----------
This command will return the results from netstat on the local system
.EXAMPLE
Invoke-DOSCommand -Command "netstat -ano" -ComputerName "SERVER1"

DESCRIPTION
-----------
This command will return the results from netstat on the remote system SERVER1
.EXAMPLE
Invoke-DOSCommand -Command "netstat -ano" -ComputerName "SERVER1" | ?{$_ -match "LISTENING"}

DESCRIPTION
-----------
This command is the same as the previous example, but here we are returning only interfaces
that are in the listening state
#>
    [CmdletBinding()] param(                
        [Parameter(Mandatory=$true)] $Command,
        [Parameter(Mandatory=$false)] $ComputerName,
        [Parameter(Mandatory=$false)] [string]$TempLocalDirPath="C:\",
        [Parameter(Mandatory=$false)] [switch]$Force
    )
    
    process{
        
        #if computername is specified assume remote system
        if($ComputerName){
        
            $tempFileName = (get-date -UFormat "%Y%m%d%H%M%S") + "DOStemp.txt"
            
            #generate local file path
            if( $TempLocalDirPath.EndsWith('\') ) {
                $localFilePath = $TempLocalDirPath + $tempFileName
            }
            else {
                $localFilePath = $TempLocalDirPath + '\' + $tempFileName
            }
            
            #generate remote file path from local path using hidden admin share
            try {
                $remoteFolderPath = "\\$ComputerName\" + (Split-Path $TempLocalDirPath -Qualifier -ErrorAction Stop).TrimEnd(":") + "$" + (Split-Path $TempLocalDirPath -NoQualifier -ErrorAction Stop)
            }
            catch {
                Write-Host "`nERROR: Bad TempLocalDirPath value" -ForegroundColor Magenta
                Write-Host "`n" $_.Exception.Message "`n" -ForegroundColor Magenta
            }
            
            #test that folder exists and is reachable
            if( !(Test-Path $remoteFolderPath) ) {
                Write-Host "`nERROR: Remote path $remoteFolderPath desn't exist or is inaccessible`n" -ForegroundColor Magenta
                return
            }
            
            #add filename to path
            if( $remoteFolderPath.EndsWith('\') ) {
                $remoteFilePath = $remoteFolderPath + $tempFileName    
            }
            else {
                $remoteFilePath = $remoteFolderPath + '\' + $tempFileName
            }
            Write-Host "`nTemp file will be located at $remoteFilePath" -ForegroundColor Cyan

            #if there is already a file with this name -Force required
            if( (Test-Path $remoteFilePath) -and !($Force) ) {
                Write-Host "`nWARNING: File $remoteFilePath Already Exists" -ForegroundColor Yellow
                Write-Host "You can use the -Force parameter to overwrite or you can" -ForegroundColor Yellow
                Write-Host "specify a different temp path using -TempLocalDirPath" -ForegroundColor Yellow
                Write-Host "the default path is C:\`n" -ForegroundColor Yellow
                return
            }

            #create remote dos command
            $cmd = "cmd /c $Command > $localFilePath"
        
            #run command as process using WMI invocation
            try {
                $processID = (Invoke-WmiMethod -Class win32_process -Name create -ArgumentList $cmd -ComputerName $ComputerName -ErrorAction Stop).ProcessID
            }
            catch {
                Write-Host "`nERROR: creating process" -ForegroundColor Magenta
                Write-Host "`n$_`n" -ForegroundColor Magenta
                return
            }
            
            #wait for process to complete
            Write-Host "`nWaiting for process $processID to complete..." -ForegroundColor Cyan -NoNewline
            while (Get-Process -Id $processID -ComputerName $ComputerName -ErrorAction SilentlyContinue) {
               Start-Sleep -Seconds 2
               Write-Host "." -ForegroundColor Cyan -NoNewline
            }
            Write-Host ""
        
            #get results from temp file
            Start-Sleep -Seconds 4
            try {
                $result = Get-Content $remoteFilePath -ErrorAction Stop
            }
            catch {
                Write-Host "`nERROR: Couldn't get file $remoteFilePath" -ForegroundColor Magenta
                Write-Host "`n" $_.Exception.Message "`n" -ForegroundColor Magenta
                return
            }
        
            #cleanup temp file
            Remove-Item $remoteFilePath -Force -ErrorAction SilentlyContinue
            if( Test-Path $remoteFilePath ) {
                Write-Host "`nWARNING: Unable to remove remote file" -ForegroundColor Yellow
            }
        }
        #otherwise run command on local system
        else {
            $result = cmd /c $Command
        }
        
        #return command results
        if($result -eq $null) {
            Write-Host "`nNothing was returned by remote command`n" -ForegroundColor Cyan
            return
        }
        else {
            return $result
        }
    }
}