Reputation: 173
So I've got a pair of Foreach loops in my script. The functions contain the requisite
[Parameter(Mandatory=$false)]
[Switch]$Logonly
pieces but I think my loops are using the wrong syntax to catch that switch value..
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"
}
}
#}
So the way I understand it is since 3 of my functions have the aforementioned [Parameter
line then I can call my script with a -Logonly
and that should be enough to be caught by the else parts of the loops. What did I do wrong here?
Current code in it's entirety:
#---------------------------------------------------------[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
}
}
#}
Upvotes: 0
Views: 412
Reputation: 60518
In PS to check if [switch]
was used as parameter (using [switch]$LogOnly
for this example):
if($LogOnly.IsPresent)
{
#Do Something
}
else
{
#Do Something else
}
Edit: Not sure what you're doing wrong, maybe the way you're calling your script or maybe because you're using ISE without clearing the param variables before running the script. Switch itself works fine in a param block in or out a function:
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:\>
Upvotes: 1
Reputation: 174690
You'll want to declare $LogOnly
as a parameter of the script - so that you can forward it to the functions you define when you execute them:
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
As you can see, the if
/else
statements are no longer required - we just pass whatever parameter arguments was passed to the script along to the function.
If splatting $PSBoundParameters
is undesirable (this might be the case if you have different parameters to forward to different functions), you can also use $PSDefaultParameterValues
to make your functions take on the parameter arguments, like this:
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
If you insist on maintaining two sets of functions, it's as simple as:
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
}
}
Upvotes: 2