似乎不应该花很长时间的Powershell脚本吗?

时间:2018-07-12 18:46:18

标签: arrays powershell optimization

因此,我有一个脚本,该脚本旨在将一些非常大的(700mb)txt文件发送到我们使用的服务的FTP,该服务会自动设置整个网域的价格。

我正在使用一个bitearray(如此处所示)将其上载到站点,并且我有一些非常基本的内置错误处理以及一些数据库绑定。

如果我们分开运行它们,它们的运行速度很快。无论出于何种原因,在完成一个程序段之后,直到开始另一个程序段的时间都是不稳定的。有时是2分钟,有时脚本会停顿40分钟,然后再移动到下一个块。

我有点假设问题是我正在为事情做更多的整理工作?还值得注意的是,即使停止脚本有时也需要15分钟。 (例如,如果我只是在脚本运行的中间点击了break,则可能需要15到20分钟的时间才能停止)

此外,就其价值而言,该脚本在最近几天的运行时方面变得更加糟糕。我不知道我们可以做些什么改变,以使其开始花费更长的时间,但是我们已经到了。

无论如何,任何见解将不胜感激。

注意:清除变量时不会清除内容变量,应该吗?        我应该保持开放吗?我认为我做不到,因为我正在使用不同的用户名连接到FTP。

这是代码(我实际上有大约12个* .txt块,但是它们是相同的,因此在这里将其减少到3个):

    #================================== SETUP BLOCK  ==================================#

#get dat email ready
$strpasswd = Get-Content "PASSWORDFILE" | ConvertTo-SecureString
$mycreds = New-Object System.Management.Automation.PSCredential ("EXCHANGEUSER",$strpasswd)
$EmailTo = 'some@email','goes@here'
$EmailFrom = 'EXCHANGEUSER'
$EmailSubject = "CA Feed Issue Undefined Subject"
$emailbody = "Body Not Yet Defined"
$SmtpServer = 'MUHSERVER'

#Opens up database session so we can send queries
$strserver = "Server\MUHDB"
$strdatabase = "logs"
$strusername = "EXCHANGEUSER"

#createsdatabaseconnection
$sqlConnection = new-object System.Data.SqlClient.SqlConnection "server='$strserver';database='$strdatabase';Integrated Security=SSPI; User ID='$strusername'; password='$strpassword'"
$sqlConnection.Open()

#define the defaultquery
$strQuery = 
"
INSERT INTO [logs].[dbo].[EventLog] (SourceID, Started, Completed, Result, Context, Machine)
values (50,1500,1500,'NOTEDEFINED','NOTDEFINED','Server\MUHCLIENTMACHINE-CAFeed')
"

#this is how I execute the command
#$sqlCommand = $sqlConnection.CreateCommand()
#$sqlCommand.CommandText = $strquery
#$sqlCommand.ExecuteReader()
#==================================Luna.txt ==================================#
##DEFINE THESE TO CREATE NEW FEEDS
$strFilename = "\\PATH\Luna.txt"
$ftp = [System.Net.FtpWebRequest]::Create("FTPLINK1")
$user = "USERNAME1"
$password = "PASSWORDREDACTED"

# create the FtpWebRequest and configure it
$ftp = [System.Net.FtpWebRequest]$ftp
# build authentication and connection
$ftp.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
$ftp.Credentials = new-object System.Net.NetworkCredential($user,$password)
$ftp.UseBinary = $true
$ftp.UsePassive = $true
$ftp.timeout = -1
#start a timer and error handling
$starttime = (get-date).ToString()
$error.Clear()
# read in the file to upload as a byte array
$content = [System.IO.File]::ReadAllBytes("$strfilename")
$ftp.ContentLength = $content.Length
# get the request stream, and write the bytes into it
$rs = $ftp.GetRequestStream()
$rs.Write($content, 0, $content.Length)
$endtime = (get-date).ToString()

#error handle
if ($error)
    {
#Assemble the Query
    $sqlresult = "THERE IS AN ERROR, Check the error email for details"
    $sqlcontext = ($strfilename + '|' + $content.length + ' bytes')
    $strquery = 
    "INSERT INTO [logs].[dbo].[EventLog] (SourceID, Started, Completed, Result, Context, Machine)
        values (50,'$starttime','$endtime','$sqlresult','$sqlcontext','Server\MUHCLIENTMACHINE-CAFEEDSCRIPT')"
#Create Command and Execute.
    $sqlCommand = $sqlConnection.CreateCommand()
    $sqlCommand.CommandText = $strQuery
    $sqlCommand.ExecuteNonQuery()

    #Send dem emails
    $emailbody = "A file for the CA Feed failed on $strfilename at " + (get-date).ToString() + " with the error '$error[0]'"
    $emailsubject = "CA Feed Failed File"
    Send-MailMessage -SmtpServer $SmtpServer -to $EmailTo -from $EmailFrom -subject $EmailSubject -Body $emailbody
    }
    else
    {
    write-host ("$strfilename" + ' Ran Without Errors')
    $sqlresult = "RAN WITHOUT ERRORS"
    $sqlcontext = ($strfilename + '|' + $content.length + ' bytes')
    $strquery = 
    "INSERT INTO [logs].[dbo].[EventLog] (SourceID, Started, Completed, Result, Context, Machine)
        values (50,'$starttime','$endtime','$sqlresult','$sqlcontext','Server\MUHCLIENTMACHINE-CAFEEDSCRIPT')"
#Create a command object.
    $sqlCommand = $sqlConnection.CreateCommand()
    $sqlCommand.CommandText = $strQuery
    $sqlCommand.ExecuteNonQuery()
    }

# be sure to clean up after ourselves and get ready for next block
Clear-Variable -Name starttime,endtime,strfilename,sqlresult,sqlcontext,ftp
$rs.Close()
$rs.Dispose()
#==================================LDE.txt ==================================#
##DEFINE THESE TO CREATE NEW FEEDS
$strFilename = "\\PATH\LDE.txt"
$ftp = [System.Net.FtpWebRequest]::Create("FTPLINK2")
$user = "USERNAME2"
$password = "PASSWORDREDACTED"


# create the FtpWebRequest and configure it
$ftp = [System.Net.FtpWebRequest]$ftp
# build authentication and connection
$ftp.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
$ftp.Credentials = new-object System.Net.NetworkCredential($user,$password)
$ftp.UseBinary = $true
$ftp.UsePassive = $true
$ftp.timeout = -1
#start a timer and error handling
$starttime = (get-date).ToString()
$error.Clear()
# read in the file to upload as a byte array
$content = [System.IO.File]::ReadAllBytes("$strfilename")
$ftp.ContentLength = $content.Length
# get the request stream, and write the bytes into it
$rs = $ftp.GetRequestStream()
$rs.Write($content, 0, $content.Length)
$endtime = (get-date).ToString()

#error handle
if ($error)
    {
#Assemble the Query
    $sqlresult = "THERE IS AN ERROR, Check the error email for details"
    $sqlcontext = ($strfilename + '|' + $content.length + ' bytes')
    $strquery = 
    "INSERT INTO [logs].[dbo].[EventLog] (SourceID, Started, Completed, Result, Context, Machine)
        values (50,'$starttime','$endtime','$sqlresult','$sqlcontext','Server\MUHCLIENTMACHINE-CAFEEDSCRIPT')"
#Create Command and Execute.
    $sqlCommand = $sqlConnection.CreateCommand()
    $sqlCommand.CommandText = $strQuery
    $sqlCommand.ExecuteNonQuery()

    #Send dem emails
    $emailbody = "A file for the CA Feed failed on $strfilename at " + (get-date).ToString() + " with the error '$error[0]'"
    $emailsubject = "CA Feed Failed File"
    Send-MailMessage -SmtpServer $SmtpServer -to $EmailTo -from $EmailFrom -subject $EmailSubject -Body $emailbody
    }
    else
    {
    write-host ("$strfilename" + ' Ran Without Errors')
    $sqlresult = "RAN WITHOUT ERRORS"
    $sqlcontext = ($strfilename + '|' + $content.length + ' bytes')
    $strquery = 
    "INSERT INTO [logs].[dbo].[EventLog] (SourceID, Started, Completed, Result, Context, Machine)
        values (50,'$starttime','$endtime','$sqlresult','$sqlcontext','Server\MUHCLIENTMACHINE-CAFEEDSCRIPT')"
#Create a command object.
    $sqlCommand = $sqlConnection.CreateCommand()
    $sqlCommand.CommandText = $strQuery
    $sqlCommand.ExecuteNonQuery()
    }

# be sure to clean up after ourselves and get ready for next block
Clear-Variable -Name starttime,endtime,strfilename,sqlresult,sqlcontext,ftp
$rs.Close()
$rs.Dispose()

1 个答案:

答案 0 :(得分:2)

我认为没有人会调试该代码。最好的选择是找到问题所在。我使用如下秒表。对其进行策略性设置:

$SW = [System.Diagnostics.Stopwatch]::new()
$SW.Start()

#Your code block goes here
Write-Host "End of Code block 1"
$SW.Elapsed.TotalSeconds

#Another code block goes here
Write-Host "End of Code block 2"
$SW.Elapsed.TotalSeconds

现在,如果您尝试突围并且花了15分钟才能做出响应,则可能是在进行操作时卡住了。在操作完成或失败之前,它无法响应。