如何解决Foreach 中的 If/else .. Else 被忽略
所以我的脚本中有一对 Foreach 循环。函数包含必要的
[Parameter(Mandatory=$false)]
[Switch]$logonly
pieces 但我认为我的循环使用错误的语法来捕获该 switch 值..
Foreach ($i in $is) {
if (-not $logonly){
$time = (Get-Date).ToString('T')
New-func1
Get-func2
Set-func3
Log-Write -LogPath $sLogFile -LineValue "========================[ $time ]==============================="
} else {
#Foreach ($Manager in $Managers){
New-func1_logonly
Get-func2
Set-func3_logonly
Log-Write -LogPath $sLogFile -LineValue "========================[ logonly ]==============================="
}
}
#}
Foreach ($Report in $ReportsTo) {
If (-not $logonly){
Remove-func4
write-host "first remove hit"
} else {
#ForEach ($Report in $ReportsTo) {
Remove-func5_logonly
write-host "Second remove hit"
}
}
#}
所以我的理解是因为我的 3 个函数有前面提到的 [Parameter
行,那么我可以用 -logonly
调用我的脚本,这应该足以被其他部分捕获循环。我在这里做错了什么?
完整的当前代码:
#---------------------------------------------------------[Initializations]--------------------------------------------------------
# Dot Source required Function Libraries
#. "\\server\e$\scripts\Logging_Functions.ps1"
. "c:\users\documents\powershell\Functions\Logging_Functions.ps1"
# Error Action
$ErrorActionPreference = 'silentlycontinue'
# Debug preference
$global:DebugPreference = "continue"
# WhatIf Preference,uncomment to run script in a logging only function
#$WhatIfPreference = $true
#----------------------------------------------------------[Declarations]----------------------------------------------------------
# Script Version
$sScriptVersion = "1.0"
Import-Module ActiveDirectory
# Log File Info
$sLogPath = "C:\Users\Documents\powershell\Logs"
#$sLogPath = "\\server\e$\Logs"
$sLogName = "Set-LitmosGroups_$(get-date -f yyyy-MM-dd_HH-mm-ss).log"
$logonlyName = "C:\Users\Documents\powershell\Logs\Set-LitmosGroups (Log Only).log"
$sLogFile = Join-Path -Path $sLogPath -Childpath $sLogName
$LogLine = $null
#$logonly = $null
# Variable Initializations
# Org Unit where the target groups reside (Litmos)
$OU = "ou=test_litmos,ou=test accounts,dc=domain,dc=net"
# Org unt containing the All Managers security group
$OU2 = "CN=All Managers,OU=Organizational,OU=Groups,DC=domain,DC=net"
# Get member of the 'ALL Managers' security group
$Managers = Get-ADGroupMember -identity $OU2 | Select-Object -expandproperty samaccountname
# Get AD groups with Report to in the name in $ou
$ReportsTo = Get-adgroup -searchbase $ou -filter "Name -like 'Report to *'" |
Select-Object -expandproperty name
$samecount = 0
$addcount = 0
Param (
[Parameter(Mandatory=$false)]
[Switch]$logonly
)
#----------------------------------------------------------[Functions]-------------------------------------------------------------
Function Get-DirectReport {
[CmdletBinding()]
param(
[Parameter(
Mandatory = $false,ValueFromPipeline = $true,ValueFromPipelineByPropertyName = $true
)]
[string] $SamAccountName,[switch] $norecurse
)
BEGIN {}
PROCESS {
$UserAccount = Get-ADUser $SamAccountName -Properties DirectReports,displayName
$UserAccount | select -ExpandProperty DirectReports | ForEach-Object {
$User = Get-ADUser $_ -Properties DirectReports,displayName,Title,EmployeeID
if ($null -ne $User.EmployeeID) {
if (-not $norecurse) {
Get-DirectReport $User.SamAccountName
}
[PSCustomObject]@{
SamAccountName = $User.SamAccountName
UserPrincipalName = $User.UserPrincipalName
displayName = $User.displayName
Manager = $UserAccount.displayName
}
}
}
}
END {}
}
Function New-bhReportToGroup {
[CmdletBinding(SupportsShouldProcess)]
$Log1 = "New group for " + $manager + " has been created."
$Log2 = "Group for " + $manager + " already exists."
#From on when you see the below line $script:<variable> that sets the scope for that variable to the entire script which means other functions can use the value
$script:ReportsTo = $ReportsTo -replace ("Report to ","")
if ($manager -notin $ReportsTo) {
new-adgroup -name "Report to $manager" -groupscope global -path $ou
$script:addcount = $addcount +1
$LogLine = $Log1
Log-Write -LogPath $sLogFile -LineValue $LogLine
}
else {
$script:samecount = $samecount + 1
$LogLine = $Log2
Log-Write -LogPath $sLogFile -LineValue $LogLine
}
}
Function New-bhReportToGroup_logonly {
#[CmdletBinding(SupportsShouldProcess)]
$Log1 = "New group for " + $manager + " would have been created in $OU."
$Log2 = "Group for " + $manager + " already exists in $OU."
$script:ReportsTo = $ReportsTo -replace ("Report to ","")
if ($manager -notin $ReportsTo) {
$Script:addcount = $addcount +1
$LogLine = $Log1
Log-Write -LogPath $logonlyName -LineValue $LogLine
}
else {
$Script:samecount = $samecount + 1
$LogLine = $Log2
Log-Write -LogPath $logonlyName -LineValue $LogLine
}
}
Function Get-bhDReports {
[CmdletBinding(SupportsShouldProcess)]
$script:directreports = Get-Directreport $manager -norecurse | Select-Object samAccountName
if ($null -ne $directreports) {
$LogLine = "Gathering direct reports for " + $manager
Log-Write -LogPath $sLogFile -LineValue $LogLine
}
else {
$LogLine = $manager + " has no reports."
Log-Write -LogPath $sLogFile -LineValue $LogLine
}
}
Function Set-bhRTGmembers {
[CmdletBinding(SupportsShouldProcess)]
# Get manager's 'report to <manager>' group again to update members
$managerReportToGroup = Get-ADGroup -SearchBase $OU -Filter "Name -like 'Report to $Manager'"
if ($managerReportToGroup) {
Add-ADGroupMember -identity $managerReportToGroup.Name -members $DirectReports
Add-ADGroupMember -identity $managerReportToGroup.name -members $Manager
$LogLine = "Report to " + $Manager + " updated."
Log-Write -LogPath $sLogFile -LineValue $LogLine
}
else {
$LogLine = "Could not find group for " + $Manager
Log-Write -LogPath $sLogFile -LineValue $LogLine
}
}
Function Set-bhRTGmembers_logonly {
#[CmdletBinding(SupportsShouldProcess)]
# Get manager's 'report to <manager>' group again to update members
$managerReportToGroup = Get-ADGroup -SearchBase $OU -Filter "Name -like 'Report to $Manager'"
if ($managerReportToGroup) {
$LogLine = "Report to " + $Manager + " would be updated with $DirectReports."
Log-Write -LogPath $logonlyName -LineValue $LogLine
}
else {
$LogLine = "Could not find group for " + $Manager
Log-Write -LogPath $logonlyName -LineValue $LogLine
}
}
Function Remove-bhOOSGroups {
[CmdletBinding(SupportsShouldProcess)]
$report = $report -replace ("Report to ","")
if ($Report -notin $managers) {
Remove-ADGroup -Identity "Report to $Report" -confirm:$false
$LogLine = $report + " user has fell out of scope,Report group removed."
Log-Write -LogPath $sLogFile -LineValue $LogLine
}
else {
Continue
}
}
Function Remove-bhOOSGroups_logonly {
#[CmdletBinding(SupportsShouldProcess)]
$report = $report -replace ("Report to ","")
if ($Report -notin $managers) {
$LogLine = $report + " user has fell out of scope,Report group would be removed."
Log-Write -LogPath $sLogFile -LineValue $LogLine
}
else {
Continue
}
}
#----------------------------------------------[ Execution ]------------------------------------------------
Foreach ($Manager in $Managers) {
if (-not $logonly) {
$time = (Get-Date).ToString('T')
write-host $logonly
New-bhReportToGroup
Get-bhDReports
Set-bhRTGmembers
Log-Write -LogPath $sLogFile -LineValue "========================[ $time ]==============================="
} else {
write-host $logonly
New-bhReportToGroup_logonly
Get-bhDReports
Set-bhRTGmembers_logonly
Log-Write -LogPath $logonlyName -LineValue "========================[ logonly ]==============================="
}
}
Foreach ($Report in $ReportsTo) {
If (-not $logonly){
Remove-bhOOSGroups
} else {
#ForEach ($Report in $ReportsTo) {
Remove-bhOOSGroups_logonly
}
}
#}
解决方法
您需要将 $LogOnly
声明为 脚本 的参数 - 这样您就可以forward it 执行定义的函数:
param(
[Parameter(Mandatory=$false)]
[switch]$LogOnly
)
function New-Thing {
param(
[Parameter(Mandatory=$false)]
[switch]$LogOnly
)
if(-not $LogOnly) {
return "Thing"
}
else {
Write-Host "Here I would have returned thing!"
}
}
# Splatting $PSBoundParameters
New-Thing @PSBoundParameters
如您所见,不再需要 if
/else
语句 - 我们只是将传递给脚本的任何参数参数传递给函数。
如果 splatting $PSBoundParameters
是不可取的(如果您有不同的参数要转发到不同的函数,可能就是这种情况),您也可以 use $PSDefaultParameterValues
使您的函数采用参数参数,如下所示:
param(
[Parameter(Mandatory=$false)]
[switch]$LogOnly,[Parameter(Mandatory=$false)]
[string]$AnotherParameter
)
# Set default param values for your custom functions
$PSDefaultParameterValues['New-Thing:LogOnly'] = $LogOnly
$PSDefaultParameterValues['Get-AnotherThing:UnrelatedParameter'] = $AnotherParameter
function New-Thing {
param(
[Parameter(Mandatory=$false)]
[switch]$LogOnly
)
# ...
}
function Get-AnotherThing {
param(
[Parameter(Mandatory=$false)]
[switch]$UnrelatedParameter
)
# ...
}
# No need to explicitly pass arguments to the functions anymore
# PowerShell will do it for us
New-Thing
Get-AnotherThing
如果坚持维护两套功能,就这么简单:
param(
[Parameter(Mandatory=$false)]
[switch]$LogOnly
)
foreach($Round in 1..5){
if(-not $LogOnly){
Write-Host "Round $Round!"
# Call Function1 here
}
else{
Write-Host "Round $Round,LogOnly!"
# Call Function1_LogOnly here
}
}
,
在 PS 中检查 [switch]
是否用作参数(在本示例中使用 [switch]$LogOnly
):
if($LogOnly.IsPresent)
{
#Do Something
}
else
{
#Do Something else
}
编辑:不确定您做错了什么,可能是您调用脚本的方式,或者可能是因为您在运行脚本之前没有清除参数变量而使用 ISE。 Switch 本身在传入或传出函数的参数块中工作正常:
PS C:\> cat $home\documents\test.ps1
param(
[string]$Test,[switch]$TestSwitch
)
if($TestSwitch.IsPresent)
{
return "Hello $Test,switch is present."
}
else
{
return "Hello $Test,switch is not present."
}
PS C:\> . $home\documents\test.ps1 -Test World -TestSwitch
Hello World,switch is present.
PS C:\> . $home\documents\test.ps1 -Test World
Hello World,switch is not present.
PS C:\>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。