【发布时间】:2019-11-01 14:48:59
【问题描述】:
这里真的很奇怪。我有一个由两部分组成的脚本,一个在 Python 中收集数据,另一个在 PowerShell 中完成所有 AD 工作。我在 Python 中使用 subprocess 和 stdout 来运行 PowerShell 脚本,而不必运行一个然后另一个。
经过进一步的开发,我意识到在某些情况下,我需要更改 CSV 文件的某些部分,然后再用 Python 处理它的最后一部分。简单使用Export-Csv,在PowerShell中运行,没问题。
将脚本作为一个整体运行,如果 PowerShell 通过 subprocess 和 stdout 编辑了 CSV,那么由于某种奇怪的原因,PowerShell 认为 CSV 中有一个额外的行并尝试将其作为新用户处理。
同样,如果代码和相同的条件都满足,并且仅通过 PowerShell 运行,则不会出现额外的行(已检查文件并且所有数据看起来都应如此,没有额外的行)。
有问题的代码行是:
#Find out if its in use
while ($Exit -eq $false)
{
$Return = UserExists $Username $Description
if($Return -eq 'User does not exist')
{
$Exit = $true
$Return = $Username
}
elseif($Return -eq 'User already exists')
{
$Exit = $true
}
elseif($Return -eq 'User does not exist but username does')
{
[STRING]$StringToAppend = $IntegerToAppend
$UserName = $userinfo['username']+ $StringToAppend
$sAMAccountName = $UserName
[INT]$IntegerToAppend = [INT]$IntegerToAppend + 1
$oldUN = $userinfo['username']
$LC = $userinfo['learnerCode']
$file = 'C:/XXX/XXX/XXXstudents.csv'
$csv = Import-Csv $file
foreach($row in $csv)
{
if ($row.UserName -eq $oldUN -And $row.LearnerCode -eq $LC) {
$row.UserName = $UserName
$row.EmailAddress = $UserName + '@XXXXX.org.uk'
}}
$csv | Export-Csv $file -NoTypeInformation;
}
}
return $Return
}
子流程代码为:
# Launch next part of script - Powershell create users
p = subprocess.Popen(["powershell.exe",
'C:/Provisioning/ProvisionStudents.ps1'],
stdout=sys.stdout)
p.communicate()
现在我觉得 PowerShell 脚本正在编辑它正在迭代的 CSV 文件这一事实很重要,应该注意。但是,我有这个几乎相同的脚本对另一个站点执行相同的操作,它没有这个问题。
有什么想法吗?
【问题讨论】:
-
是否有理由不使用不同的文件进行更改?让每个阶段使用不同的文件,“踩到自己”的问题似乎消失了。
-
似乎没有必要创建一个几乎相同的文件,因为我只会更改每个学生的 2 个值,并且只有当他们的用户名已经被占用时......我会继续尝试使用不同的文件和查看问题是否仍然存在
-
另外,只是想如果更改同一个文件会导致问题与仅在 PowerShell 中运行它时不同吗?
-
多线程访问文件是经典的“陷阱!”之一情况。 [grin] 强烈建议您不要这样做,除非需要...然后非常强烈建议您使用线程安全技术来处理出现的各种问题.
标签: python-3.x powershell subprocess stdout