2012-04-11 176 views
3

我有这个PowerShell脚本运行。第一次运行时它运行得非常完美,第二次运行时我得到的错误是.csv不能访问“,因为它正在被另一个进程使用。任何想法脚本的哪个部分”抓住“文件和我怎么可以让它不了了之结束Powershell使用文件? “被另一个进程使用”

clear 
set-executionpolicy remotesigned 
# change this to the directory that the script is sitting in 
cd d:\directory 

############################################# 
# Saves usernames/accountNumbers into array # 
# and creates sql file for writing to # 
############################################# 


# This is the location of the text file containing accounts 
$accountNumbers = (Get-Content input.txt) | Sort-Object 
$accountID=0 
$numAccounts = $accountNumbers.Count 
$outString =$null 
# the name of the sql file containing the query 
$file = New-Item -ItemType file -name sql.sql -Force 


################################### 
# Load SqlServerProviderSnapin100 # 
################################### 

if (!(Get-PSSnapin | ?{$_.name -eq 'SqlServerProviderSnapin110'})) 
{ 
    if(Get-PSSnapin -registered | ?{$_.name -eq 'SqlServerProviderSnapin110'}) 
    { 
     add-pssnapin SqlServerProviderSnapin100 
     Write-host SQL Server Provider Snapin Loaded 
    } 
    else 
    { 
    } 
} 
else 
{ 
Write-host SQL Server Provider Snapin was already loaded 
} 


################################# 
# Load SqlServerCmdletSnapin100 # 
################################# 

if (!(Get-PSSnapin | ?{$_.name -eq 'SqlServerCmdletSnapin100'})) 
{ 
    if(Get-PSSnapin -registered | ?{$_.name -eq 'SqlServerCmdletSnapin100'}) 
    { 
     add-pssnapin SqlServerCmdletSnapin100 
     Write-host SQL Server Cmdlet Snapin Loaded 
    } 
    else 
    { 

    } 
} 
else 
{ 
    Write-host SQL Server CMDlet Snapin was already loaded 
} 




#################### 
# Create SQL query # 
#################### 

# This part of the query is COMPLETELY static. What is put in here will not change. It will usually end with either % or ' 
$outString = "SELECT stuff FROM table LIKE '%" 
# Statement ends at '. loop adds in "xxx' or like 'xxx" 
IF ($numAccounts -gt 0) 
{ 
    For ($i =1; $i -le ($AccountNumbers.Count - 1); $i++) 
    { 
     $outString = $outstring + $AccountNumbers[$accountID] 
     $outString = $outString + "' OR ca.accountnumber LIKE '" 
     $accountID++ 
    } 
    $outString = $outString + $AccountNumbers[$AccountNumbers.Count - 1] 
} 
else 
{ 
    $outString = $outString + $AccountNumbers 
} 
# This is the end of the query. This is also COMPLETELY static. usually starts with either % or ' 
$outString = $outString + "%'more sql stuff" 
add-content $file $outString 
Write-host Sql query dynamically written and saved to file 



########################### 
# Create CSV to email out # 
########################### 

#Make sure to point it to the correct input file (sql query made above) and correct output csv. 
Invoke-Sqlcmd -ServerInstance instance -Database database -Username username -Password password -InputFile sql.sql | Export-Csv -Path output.csv 



#################################### 
# Email the CSV to selected people # 
#################################### 

$emailFrom = "to" 
$emailTo = "from" 
$subject = "test" 
$body = "test" 
$smtpServer = "server" 
# Point this to the correct csv created above 
$filename = "output.csv" 

$att = new-object Net.mail.attachment($filename) 
$msg = new-object net.mail.mailmessage 
$smtp = new-object Net.Mail.SmtpClient($smtpServer) 

$msg.from = $emailFrom 
$msg.to.add($emailto) 
$msg.subject = $subject 
$msg.body = $body 
$msg.attachments.add($att) 

$smtp.Send($msg) 
+0

您是否试图在脚本开始时检查文件是否存在,如果存在,请将其删除。我看不出什么是锁定文件,但我的猜测是Invoke-Sqlcmd。 – Gisli 2012-04-11 21:05:54

回答

2

你可以尝试在加个结尾:?

$att.Dispose() 
$msg.Dispose() 
$smtp.Dispose() 
+0

很酷谢谢。我应该也做$ file.Dispose()? – mhopkins321 2012-04-13 15:07:44

+0

我不这么认为。 – JPBlanc 2012-04-13 15:41:12

1

你也可以尝试使用一个工具,如procmon,看看是否脚本每当它获得文件上的一个锁并且不释放它时,它就会执行。另外,由于(假设)问题出在.csv文件上,所以你可以将它加载为字节数组而不是通过g它是作为附件的路径。这样文件应该被读取一次,而不是锁定。

相关问题