Script For NetBackup, Global Variable Problems

Welcome Forums General PowerShell Q&A Script For NetBackup, Global Variable Problems

Viewing 16 reply threads
  • Author
    Posts
    • #214812
      Participant
      Topics: 8
      Replies: 50
      Points: 111
      Rank: Participant

      Hello all ^^,

      I’m scripting something for change the scedule of a NetBackup Policy.

      I’m using  a windows 2016 server with Netbackup v 8.1.1

      My problem is than 2 Global Variable seems to loose the value when the script change of function.

      The variables is $Global:PolicyName and $Global:StopTime.

      They take teir value in the GetInfoSched Function, and when i leave this function the variable is $null.

      #Déclaration des path utilisés
      $PathConfig = "C:\Admin\ConfigPolicies"
      $PathNBUcmd = "C:\Program Files\Veritas\NetBackup\bin"
      $PathNBUadmincmd = "C:\Program Files\Veritas\NetBackup\bin\admincmd"
      $PathResult = "c:\Admin\Result"
      
      #Déclaration des Variables Globales
      $Global:Startime = $null
      $Global:StopTime = $null
      $Global:ChoixMenu = $null
      $Global:Boucle = $null
      $Global:ScheduleLabel = $null
      $Global:ChoixSched = $null
      $Global:PolicyName 
      $Global:Jour = $null
      
      Set-Location $PathNBUadmincmd
      #Faire un Backup de la configuration des schedules de ttes les policies
      #Menu des Opérations disponibles
      
      
      
      Function Menu(){
          Write-Host "Opération disponible :"
          Write-Host "1. Changer le jour et heure d'un Schedule d'une Policy"
          Write-Host "2. Remettre les schedules a l'origine"
          $Global:ChoixMenu = Read-Host "Selectioner l'operation souhaité"
      }
      
      $Var = "PolicyName"
      Function GetInfosSch(){
          T("Entrer GetInfoSch", "PolicyName", $PolicyName)
          $CritereSelection = Read-Host "Donner votre critere de sélection"
          $ListPN = .\bppllist.exe -allpolicies -U | Find /I "Policy Name"
          ForEach($Policy in $ListPN){
              $PolicyName = ($Policy.split(":")[1]).replace(" ","") | Where{$_ -like "*$CritereSelection*"} 
          }
          #$Start = Read-Host "Date et Heure de début de sauvegarde, ex: mm/jj/YYYY 10:30"
          #$Stop = Read-Host "Date et Heure de fin, ex: mm/jj/YYYY 11:30"
          $Start = "02/04/2020 16:00"
          $Stop = "02/04/2020 16:30"
          $Jour = (Get-Date -Date $Start.split(" ")[0] -UFormat "%A").Replace(" ","")
          $StartTime = New-TimeSpan -Start ($Start.Split(" ")[0]) -End $Start 
          $StartTime = $StartTime.TotalSeconds
          $tdiff = New-TimeSpan -Start $Start -End $Stop
          $StopTime = $tdiff.TotalSeconds
      
          #Recuperation des informations des schedules de la Policy
          $Schedules = .\bpplsched.exe RGS_MGMT_P -U | Where{$_ -like "*Schedule*"}
      
          #Choix et Récuperation des PolicyName et ScheduleLabel 
          $Sched1 = ($Schedules[0].split(":")[1]).replace(" ","")
          $Sched2 = ($Schedules[1].split(":")[1]).replace(" ","")
          Write-Host "1. $Sched1"
          Write-Host "2. $Sched2"
          $ChoixSched = Read-Host "Sélectionner le schedule a modifier" 
          Switch($ChoixSched){
              1{$Global:ScheduleLabel = $Sched1}
              2{$Global:ScheduleLabel = $Sched2}
          }
          Write-Host "#============================================================================# "
          Write-Host "Récapitulations des informations avant modifications des Schedules:" 
          Write-Host "Critere de sélection: $CritereSelection"
          Write-Host "PolicyName: $PolicyName"
          Write-Host "Schedule Label: $ScheduleLabel"
          Write-Host "Jour: $Jour"
          Write-Host "Date et Heure start backup: $Start"
          Write-Host "Date et Heure stop backup: $Stop"
          Write-Host "StartTime en seconde: $StartTime"
          Write-Host "StopTime en seconde: $StopTime"
          $Global:Boucle = Read-Host "Si tout est ok, Yes ou Non"
          T("Sortie GetInfoSch","PolicyName",$PolicyName)
      }
      
      #A revoir !
      Function BackupSched(){
          T("Entrée Backup","PolicyName",$PolicyName)
          Set-Location $PathNBUadmincmd
          Write-Host "Passe dans la fonction BackupSched"
          $ListPN = .\bppllist.exe -allpolicies -U | Find /I "Policy Name" 
          Write-Host "$ListPN"
          $Date = Get-Date -UFormat "-%d-%m-%Y"
          $TP = Test-Path -Path "$PathConfig\AllPolicies.txt"
          If($TP -eq "*True*"){Remove-Item "$PathConfig\AllPolicies.txt"}
          ForEach($Policy in $ListPN){
              $Policy = ($Policy.split(":")[1]).replace(" ","") 
              Write-Host "Policy: $policy"
              $PolicyList = $Policy | Out-File "$PathConfig\AllPolicies.txt" -Append
              .\bpplsched.exe $Policy -l | Out-File "$PathConfig\Config-$Policy$Date.txt"
          }
          Write-Host "Policy: $Policy"
          Write-Host "Fin de la fonction Backup"
          T("Sortie Backup","PolicyName",$PolicyName)
      }
      
      
      # A Verifier !!!
      Function ModificationSched(){
          T("Entrée ModifSched","PolicyName",$PolicyName)
          Write-Host "Début de la fonction Modification"
          Write-Host "PolicyName: $Global:PolicyName"
          Write-Host "ScheduleLabel: $ScheduleLabel"
          Write-Host "StartTime: $StartTime"
          Write-Host "StopTime: $StopTime"
          Switch($Jour){
              Dimanche{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 $StartTime $StopTime -1 0 0 -2 0 0 -3 0 0 -4 0 0 -5 0 0 -6 0 0}
              Lundi{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 $StartTime $StopTime -2 0 0 -3 0 0 -4 0 0 -5 0 0 -6 0 0}
              Mardi{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 0 0 -2 $StartTime $StopTime -3 0 0 -4 0 0 -5 0 0 -6 0 0}
              Mercredi{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 0 0 -2 0 0 -3 $StartTime $StopTime -4 0 0 -5 0 0 -6 0 0}
              Jeudi{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 0 0 -2 0 0 -3 0 0 -4 $StartTime $StopTime -5 0 0 -6 0 0}
              Vendredi{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 0 0 -2 0 0 -3 0 0 -4 0 0 -5 $StartTime $StopTime -6 0 0}
              Samedi{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 0 0 -2 0 0 -3 0 0 -4 0 0 -5 0 0 -6 $StartTime $StopTime}
          }
          Write-Host "Modification éffectué"
          T("Sortie ModifSched","PolicyName",$PolicyName)
      }
      
      
      Function RollBack(){
          $PolicyList = Get-Content "$PathConfig\AllPolicies.txt"
          ForEach($Policy in $PolicyList){
              $ConfigRef = Get-Content "$PathConfig\Config-$Policy*.txt"
              $ConfigDiff = .\bpplsched.exe $Policy -l
              $PolicyName = $Policy
              If(Compare-Object -ReferenceObject $ConfigRef -DifferenceObject $ConfigDiff){
                  Write-Host "Les fichiers sont Differents"
                  $Diff = Compare-Object -ReferenceObject $ConfigRef -DifferenceObject $ConfigDiff   
                  $DiffCsv = $Diff | Export-Csv "$PathConfig\config.csv" -Delimiter ","
                  $Diff = Import-Csv "$PathConfig\config.csv" -Delimiter ","
                  $Conf =  $Diff[1].InputObject 
                  $i=0
                  $TabVal = @()
                  $TabPos = @()
                  While($i -le 14){
                      If($Diff.split(" ")[$i] -notlike "0"){
                          $Val = $Diff.split(" ")[$i]
                          $TabVal += $Val
                          $TabPos += $i
                      }
                      $i++
                  }
                  #Rechercher le schedule Label qui a été modifié
              Switch($TabPos[1]){
                  1{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 $StartTime $StopTime -1 0 0 -2 0 0 -3 0 0 -4 0 0 -5 0 0 -6 0 0}
                  3{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 $StartTime $StopTime -2 0 0 -3 0 0 -4 0 0 -5 0 0 -6 0 0}
                  5{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 0 0 -2 $StartTime $StopTime -3 0 0 -4 0 0 -5 0 0 -6 0 0}
                  7{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 0 0 -2 0 0 -3 $StartTime $StopTime -4 0 0 -5 0 0 -6 0 0}
                  9{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 0 0 -2 0 0 -3 0 0 -4 $StartTime $StopTime -5 0 0 -6 0 0}
                 11{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 0 0 -2 0 0 -3 0 0 -4 0 0 -5 $StartTime $StopTime -6 0 0}
                 13{.\bpplschedwin $PolicyName $Global:SheduleLabel -0 0 0 -1 0 0 -2 0 0 -3 0 0 -4 0 0 -5 0 0 -6 $StartTime $StopTime}
              }
      
              }
              Else{
                  Write-Host "Les fichiers sont identiques"
              }
          }
      }
      
      
      
      Function T([string]$orig, [string]$var, [string]$val){
          Write-Host "#####################################################"
          Write-Host "Oigine: $Orig"
          Write-Host "Entrer dans la fonction T"
          Write-Host "$var : $val"
          Write-Host "PolicyName: $Global:PolicyName"
          Write-Host "ScheduleLabel: $ScheduleLabel"
          Write-Host "StartTime: $StartTime"
          Write-Host "StopTime: $StopTime"
          Write-Host "#####################################################"
      }
      
      
      ###############Deroulement du Script##################
      do{
          Menu
          GetInfosSch
      }
      Until($Global:Boucle -like "*Yes*")
      if ($Global:ChoixMenu -eq 1){
          BackupSched
          ModificationSched
      }
      Else {
          RollBack
      }
      
      
      Set-Location "C:\Admin"

      Thx for help.

    • #214827
      Participant
      Topics: 12
      Replies: 1607
      Points: 2,495
      Helping Hand
      Rank: Community Hero

      First, using Global Variables is almost always a bad practice. Powershell is designed to pass data in a pipeline, but you should be passing data to the function and producing a object as output (if necessary). Look at the example below how a function passes data to a function, no global variables in the function. Even if I create a global variable (e.g. Color), it is passed to the function, not a global variable:

      Function Menu {
          [CmdletBinding()]
          param (
              $Color='Green'
          )
          Write-Host "Opération disponible :" -ForegroundColor $Color
          Write-Host "1. Changer le jour et heure d'un Schedule d'une Policy" -ForegroundColor $Color
          Write-Host "2. Remettre les schedules a l'origine" -ForegroundColor $Color
          $Choix = Read-Host "Selectioner l'operation souhaité"
          switch -Regex ($Choix) {
              "1|2" {
                  [pscustomobject]@{
                      ChoixMenu = $Choix
                  }
              }
              default {
                  Throw 'Must be a 1 or 2'
              }
          }
      }
      
      Function GetInfosSch {
          [CmdletBinding()]
          param (
              [Parameter(
                  Mandatory=$true,
                  ValueFromPipelineByPropertyName=$true
              )]
              [int]$ChoixMenu
          )
      
          Write-Verbose -Message ('User chose {0}' -f $ChoixMenu)
      
          $stopTime = switch ($ChoixMenu) {
              1 {(Get-Date).AddDays(1)}
              2 {(Get-Date).AddDays(2)}
          }
      
          [pscustomobject]@{
              StartTime = Get-Date
              StopTime  = $stopTime
          }
      
      }
      
      
      Function ModificationSched {
          [CmdletBinding()]
          param (
              [Parameter(
                  Mandatory=$true,
                  ValueFromPipelineByPropertyName=$true
              )]
              [datetime]$StartTime,
              [Parameter(
                  Mandatory=$true,
                  ValueFromPipelineByPropertyName=$true
              )]
              [datetime]$StopTime
          )  
         
          Write-Verbose -Message ("Setting schedule with start {0} and stop {1}" -f $StartTime, $StopTime)
      }
      
      
      $Color = 'Cyan'
      Menu -Color $Color | GetInfosSch -Verbose | ModificationSched -Verbose
      

      Output:

      
      Opération disponible :
      1. Changer le jour et heure d'un Schedule d'une Policy
      2. Remettre les schedules a l'origine
      Selectioner l'operation souhaité: 1
      VERBOSE: User chose 1
      VERBOSE: Setting schedule with start 4/2/2020 6:11:54 PM and stop 4/3/2020 6:11:54 PM
      
      Opération disponible :
      1. Changer le jour et heure d'un Schedule d'une Policy
      2. Remettre les schedules a l'origine
      Selectioner l'operation souhaité: 2
      VERBOSE: User chose 2
      VERBOSE: Setting schedule with start 4/2/2020 6:12:22 PM and stop 4/4/2020 6:12:22 PM
      
      Opération disponible :
      1. Changer le jour et heure d'un Schedule d'une Policy
      2. Remettre les schedules a l'origine
      Selectioner l'operation souhaité: 3
      Must be a 1 or 2
      At line:15 char:13
      +             Throw 'Must be a 1 or 2'
      +             ~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo          : OperationStopped: (Must be a 1 or 2:String) [], RuntimeException
          + FullyQualifiedErrorId : Must be a 1 or 2
      

      Now, to answer your question about scope, creating the variable $Global:StartTime doesn’t persist if you use a variable $StartTime in your function, you have to create it as $Global:StartTime in the function or the scope is function only.

    • #214941
      Participant
      Topics: 8
      Replies: 50
      Points: 111
      Rank: Participant

      Hello Rob,

       

      Thx to for your reply ^^

      First i will try to understand what you explain to me and come back to you 😉

       

    • #215082
      Participant
      Topics: 8
      Replies: 50
      Points: 111
      Rank: Participant

      I do’t understand really what you want to tell me about Create the $Global:Variable in the function or the scope is the function only …

      Could you explain to me ?

       

    • #215094
      Participant
      Topics: 8
      Replies: 50
      Points: 111
      Rank: Participant

      Ok it’s good, i understand what you have said to me.

      I just have to call always, my variable “$Global:PolicyName”, and not on time “$Global:PolicyName” and other “$PolicyName”.

      I think remember in my course of Powershell, that when we create a Global Variable, we could call it With ou without $Global.

      Ok Thx Rob 😉

       

    • #215133
      Participant
      Topics: 12
      Replies: 1607
      Points: 2,495
      Helping Hand
      Rank: Community Hero

      A function has it’s own private scope. When you are setting a variable in a function like this:

      $myVar = '123'
      

      This is setting a variable in the function scope which takes precedence over global. In your scenario, using global variables (which again is bad), you should GET and SET using the $Global container:

      $Global:myvar = '123'
      

      https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-7
      https://adamtheautomator.com/powershell-global-variable/

    • #215730
      Participant
      Topics: 8
      Replies: 50
      Points: 111
      Rank: Participant

      Hello Robs,

       

      I’m come back to you ,

      I’have some problems with the Global Variable, so  i have two solution do without Function or with finction but without Global Variable !

      But How to pass a Variable to another fonction ? i really don’t understand…

       

      Thx for help.

    • #215733
      Participant
      Topics: 4
      Replies: 2231
      Points: 5,414
      Helping Hand
      Rank: Community MVP

      But How to pass a Variable to another fonction ?

      As parameter of the function. 😉

    • #215736
      Participant
      Topics: 8
      Replies: 50
      Points: 111
      Rank: Participant

      You said that using the Global Variable is bad, so how to pass variable to another function without using $Global:Variable ?

    • #215745
      Participant
      Topics: 4
      Replies: 2231
      Points: 5,414
      Helping Hand
      Rank: Community MVP

      … so how to pass variable to another function without using $Global:Variable ?

      As parameter of the function. 😉

    • #215757
      Participant
      Topics: 8
      Replies: 50
      Points: 111
      Rank: Participant

      I’ve Understand how to pass a variable to the fonction where the variable is come from.

      But how pass a variable of the fonction One to the function Two ?

       

    • #215760
      Participant
      Topics: 8
      Replies: 50
      Points: 111
      Rank: Participant

      I’ve try this , like Rob said :

       

      Function One(){
          $ChoixMenu = 1
          [pscustomobject]@{
              ChoixMenu = $ChoixMenu
              }
          Write-Output "ChoixMenu-One: $ChoixMenu"
      }
      
      Function Two(){
          [CmdletBinding()]
          param (
              [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
              [int]$ChoixMenu
          )
          Write-Output "ChoixMenu-Two: $ChoixMenu"
      }
      
      One
      Two $ChoixMenu 

      But the result is not good  for me :

       

      PS C:\Users\Administrateur.WIN-VLGC27MQG0C> C:\Admin\TRy.ps1
      
      ChoixMenu
      ---------
              1
      ChoixMenu-One: 1
      ChoixMenu-Two: 0
      • This reply was modified 1 month, 2 weeks ago by Renaud.
    • #215769
      Participant
      Topics: 4
      Replies: 2231
      Points: 5,414
      Helping Hand
      Rank: Community MVP

      You might stop using the same variable names to reduce the confusion. 😉

      Function One{
          $PramOne = 1
          $PramOne
      }
      
      Function Two {
          [CmdletBinding()]
          param (
              [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
              [int]$ParamTwo
          )
         "ReturnValue function Two: $ParamTwo"
      }
      
      Two -ParamTwo (One)

      You could also save the output of function one in a variable and pass this to function two like this:

      $outputOfFunctionOne = One
      Two -ParamTwo $outputOfFunctionOne 
    • #215772
      Participant
      Topics: 8
      Replies: 50
      Points: 111
      Rank: Participant

      Ah the function overwrite…Ok.
      New try, i think i will be crazy soon !

      Function One(){
          $ChoixMenuOne = 1
      }
      
      Function Two(){
          [CmdletBinding()]
          param (
              [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
              [int]$ChoixMenuTwo
          )
          Write-Output "ChoixMenuTwo: $ChoixMenuTwo"
      }
      
      Two -ChoixMenuTwo (One)

      0, perhaps The number of my skill in powershell …

    • #215778
      Participant
      Topics: 8
      Replies: 50
      Points: 111
      Rank: Participant

      Ok, even if my try works…a day !

       

      I don’t think it’s usefull for my script, i’m wrong ?

    • #215781
      Participant
      Topics: 4
      Replies: 2231
      Points: 5,414
      Helping Hand
      Rank: Community MVP

      0, perhaps The number of my skill in powershell …

      You assigned a value to the variable in your function one bit you did not output it. 😉

      So instead of

      Function One(){
          $ChoixMenuOne = 1
      }

      use this

      Function One(){
          $ChoixMenuOne = 1
          $ChoixMenuOne
      }
    • #215787
      Participant
      Topics: 8
      Replies: 50
      Points: 111
      Rank: Participant

      We need do output it…Hmm Ok  it’s work…but i don’t really understand, my skill certainly ^^

       

      Ok ok.

       

      Now how can i use this method for my script…i will look that.

       

      Thx again Olaf and Robs 😉

      Have a nice days, has you can 😉

Viewing 16 reply threads
  • You must be logged in to reply to this topic.