Share via


Passing variables to function fails - empty variable

Question

Tuesday, November 15, 2016 3:54 PM

I am having trouble with passing variables to a function. I've used Debug statements and manually debugged it myself by tracing it. The variable is non empty before the function call, but once I get into the function, it is null. I'm lost. I've looked at the code over and over again and I can't figure out what I'm doing wrong. I'm sure it's something obvious, but I just need another set of eyes to show me.

Brian

function main
{
    
    
    
    #region test database connectivity
    #test-databaseRead
    #endregion
    
    #region add to exclusion list, add to SCCM apps list
    #Add-ToExclusions
    #endregion
    
    
    #region function scoped variables
    $computerNames = Get-Content "X:\ircstm\PCTechs\EUC Central Services\Refresh Script\Computers.txt"
    $GarbageApps = Get-Content -path "X:\ircstm\PCTechs\EUC Central Services\Refresh Script\GarbageApps.txt"
    $SCCMApps = Get-Content -path "X:\ircstm\PCTechs\EUC Central Services\Refresh Script\SccmApps.txt"

...


Add-RemoteDataToTemp -computerName $computerName -SSCMApps $SCCMApps -GarbageApps $GarbageApps -temp $temp

...

function Add-RemoteDataToTemp ($computerName, $SCCMApps, $GarbageApps, $temp)
{

...

$installedApps = $(Get-Apps -computerName $computerName)
        Write-Debug "InstalledApps= $installedApps"
        
        Get-AppsToInstall -installedApps $installedApps -SCCMApps $SCCMApps -GarbageApps $GarbageApps -sccmAppsToInstall $sccmAppsToInstall -manualAppsToInstall $manualAppsToInstall

...

}

unction Get-AppsToInstall ($installedApps, $SCCMapps, $GarbageApps, $sccmAppsToInstall, $manualAppsToInstall)
{
    $installedApps | ForEach-Object {
        $currentApp = $_
        if (Compare-Object -ReferenceObject $currentApp -DifferenceObject $SCCMapps -IncludeEqual -ExcludeDifferent)
        {
            $sccmAppsToInstall += $currentApp #in master SCCM app list
        }
        else
        {
            if (!(Compare-Object $currentApp $GarbageApps -IncludeEqual -ExcludeDifferent))
            {
                $manualAppsToInstall += $currentApp  #NOT in master Garbage app list
            }
        }
    }
    
}

All replies (19)

Tuesday, November 15, 2016 4:11 PM

IN function main you defined variable $computerNames but when calling another function you are passing $computerName, which does not exist, therefore it will be $null

Variables defined in a function are only scoped to that function, you may pass the data in it to another functions variable, but doesn't look like that is what you are doing.

If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.


Tuesday, November 15, 2016 4:13 PM

What function?  What variable?

You seem to have functions inside of functions.  This will not work.

Variables defined in one function will not be visible inside of another function.  All variables are locally scoped and only variables defined at teh root of the script or session are globally visible by default.

help about_scopes

\(ツ)_/


Tuesday, November 15, 2016 4:17 PM

What function?  What variable?

You seem to have functions inside of functions.  This will not work.

Variables defined in one function will not be visible inside of another function.  All variables are locally scoped and only variables defined at teh root of the script or session are globally visible by default.

help about_scopes

\(ツ)_/

I'm not sure where you are seeing "functions inside of functions". I know I don't have that. The '...' denotes that there is code that is not relevant to this issue, so I didn't include it.


Tuesday, November 15, 2016 4:19 PM

IN function main you defined variable $computerNames but when calling another function you are passing $computerName, which does not exist, therefore it will be $null

Variables defined in a function are only scoped to that function, you may pass the data in it to another functions variable, but doesn't look like that is what you are doing.

If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.

I actually create a variable - "computerName" in Main inside of a ForEach-Object block: "$computerName = $_"


Tuesday, November 15, 2016 4:20 PM

A partial and broken post of a script is not helpful. You also need to explicitly state what function and variable you are talking about.  Where is the variable defined?  Where is it being used that it is null or missing?  We cannot guess at what you are seeing or which variable is the issue.

As noted - variables defined in a function do not exist after the function exits.

Also functions must be defined before they are called.  You are calling a function before you have defined it.

\(ツ)_/


Tuesday, November 15, 2016 4:22 PM

IN function main you defined variable $computerNames but when calling another function you are passing $computerName, which does not exist, therefore it will be $null

Variables defined in a function are only scoped to that function, you may pass the data in it to another functions variable, but doesn't look like that is what you are doing.

If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.

I actually create a variable - "computerName" in Main inside of a ForEach-Object block: "$computerName = $_"

You cannot create a variable inside of a function as it will be removed when the function exits.

\(ツ)_/


Tuesday, November 15, 2016 4:33 PM

Also functions must be defined before they are called.  You are calling a function before you have defined it.

\(ツ)_/

Good point, didn't even notice that off first hand. But then again, the posted script isn't really well formatted or designed.

If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.


Tuesday, November 15, 2016 8:18 PM

The variable in question is $SCCMApps, which is created in main. I will post my entire script if that will help. The variable is used as a master list of all our SCCM apps on our server, and it compares those to the list of installed apps on the system.

<#  
    .NOTES
    ===========================================================================
     Created with:  SAPIEN Technologies, Inc., PowerShell Studio 2015 v4.2.81
     Created on:    5/1/2015 8:43 AM
     Created by:    Legacy Health
     Organization:  Legacy Health
     Filename:      
    ===========================================================================
    .DESCRIPTION
        A description of the file.
    
#>
#Requires -Version 4

Import-Module "X:\ircstm\PCTechs\~~TOOLBOX~~\Powershell Modules\ActiveDirectory\ActiveDirectory.psd1"
Import-Module "X:\ircstm\PCTechs\~~TOOLBOX~~\Powershell Modules\PSExcel\1.0.2\PSExcel.psd1"
Import-Module "X:\ircstm\PCTechs\~~TOOLBOX~~\Powershell Modules\Remote_PSRemoting\Remote_PSRemoting.psd1"
Import-Module "X:\ircstm\PCTechs\~~TOOLBOX~~\Powershell Modules\Search-Registry\Search-Registry.psm1"
Import-Module "X:\ircstm\PCTechs\~~TOOLBOX~~\Powershell Modules\Get-RemoteProgram\Get-RemoteProgram.psm1"


#region GLOBAL VARIABLES
#$databasePath = "X:\ircstm\PCTechs\wNumberDBreplacement-DONOTUSE\wNumberDB.dev.accdb"
#endregion



function main
{
    
    
    
    #region test database connectivity
    #test-databaseRead
    #endregion
    
    #region add to exclusion list, add to SCCM apps list
    #Add-ToExclusions
    #endregion
    
    
    #region function scoped variables
    $computerNames = Get-Content "X:\ircstm\PCTechs\EUC Central Services\Refresh Script\Computers.txt"
    $GarbageApps = Get-Content -path "X:\ircstm\PCTechs\EUC Central Services\Refresh Script\GarbageApps.txt"
    $SCCMApps = Get-Content -path "X:\ircstm\PCTechs\EUC Central Services\Refresh Script\SccmApps.txt"
    
    $final = @()
    $monitorInfo = @()
    $current = 1
    #endregion
    
    $computerNames | ForEach-Object {
        #region temp variables
        #Start-Job -Name GetSystemInfo -ScriptBlock {

        $computerName = $_
        Write-Debug $computerName
        
        #$sccmPhoneBookRecord = Get-SCCMPhoneBookRecord -name $computerName
        $temp = New-Object psobject
        
        #endregion
        
        
        #current element counter UI
        Write-Output "$current of $($computerNames.count)"
        $current++
        
        
        #region populate temp object
        $temp | Add-Member -MemberType 'NoteProperty' -Name ComputerName -Value $computerName                           #computer name
        #IF ONLINE
        if (Test-Connection -ComputerName $computerName -Count 1 -Quiet)
        {
            [System.Array]$monitorInfo = Get-MonitorInfo $computerName
            Add-RemoteDataToTemp -computerName $computerName -SSCMApps $SCCMApps -GarbageApps $GarbageApps -temp $temp      #remotely gathered information
            Add-MonitorInfoToTemp -monitorInfo $monitorInfo -temp $temp                                                             #monitor info
            #if ($sccmPhoneBookRecord) { add-SccmInfoToTemp -sccmPhoneBookRecord $sccmPhoneBookRecord -temp $temp }                     #records from database
            #endregion
        }
        #IF OFFLINE
        else
        {
            create-schemaFinal -offline | Where-Object { $_ -ne 'ComputerName' } | ForEach-Object {
                $name = $_
                $temp | Add-Member -MemberType 'NoteProperty' -name $name -Value 'offline'
            }
        }
        #endregion
        
        
        #region add to final output
        $final += $temp
        Write-Debug $temp
        #endregion
        
    }
    
    #region create spreadsheet
    $schemaFinal = create-schemaFinal $final
    #$final | Select-Object $schemaFinal | export-xls -Path "X:\ircstm\PCTechs\EUC Central Services\Refresh Script\output\_$(Get-Date -Format MM.dd.yyyy.hh.mm.ss).xlsx" -NoTypeInformation
    #$final | select-object $schemaFinal | Export-XLSX -Path "X:\ircstm\PCTechs\EUC Central Services\Refresh Script\output\_$(Get-Date -Format MM.dd.yyyy.hh.mm.ss).xlsx"
    $final | select $schemaFinal | Export-Csv "X:\ircstm\PCTechs\EUC Central Services\Refresh Script\output\_$(Get-Date -Format MM.dd.yyyy.hh.mm.ss).csv" -NoTypeInformation
    Write-Output "Script Completed."
    #endregion
}


function Get-IPInfo ($computerName)
{
    #$username = "lhsnt\bembree"
    #$password = ConvertTo-SecureString -String "Macey810" -AsPlainText -Force
    #$creds = New-Object System.Management.Automation.PSCredential $username, $password
    try
    {
        $IPInfo = gwmi -Class win32_networkadapterconfiguration -ComputerName $computerName | Where-Object { (($_.ipenabled -eq $true) -and ($_.ipaddress -like "10.*")) } -ErrorAction 'Stop' | select *
    }
    
    catch { $IPInfo = $null }
    Write-Debug $IPInfo
    return $IPInfo
}


<#
function Add-ToExclusions
{
    $GarbageApps = Get-Content -path "X:\ircstm\PCTechs\EUC Central Services\Refresh Script\GarbageApps.txt"
    $SCCMapps = Get-Content -path "X:\ircstm\PCTechs\EUC Central Services\Refresh Script\SCCMapps.txt"
    
    if ($addToGarbage)
    {
        Add-ToGarbage $addToGarbage
        Clear-Variable addToGarbage
        $addToGarbage > addToGarbage.txt
        Remove-Variable addToGarbage
    }
    if ($addToSCCM)
    {
        Add-ToSCCM $addToSCCM
        Clear-Variable addToSCCM
        $addToSCCM > addToSCCM.txt
        Remove-Variable addToSCCM
    }
}

#>

<#
function Add-ToGarbage
{
    param
    (
        [parameter(Mandatory = $true)]
        [System.String[]]$addToGarbage
    )
    
    begin
    {
        try
        {
            #open database connection to Access
            $conn = New-Object system.Data.OleDB.OleDbConnection
            $conn.connectionstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$databasePath"
            $conn.Open()
        }
        catch
        {
            if ($conn) { Remove-Variable conn }
            Write-Output "Could not open connection to database. Garbage list not updated."
            return
        }
    }
    process
    {
        $addToGarbage | ForEach-Object {
            $toInsert = $_
            try
            {
                #define insert query
                $query = "INSERT INTO Garbage (applicationName) VALUES('$toInsert')"
                
                #create oledb command for insert, update, or delete
                $cmd = New-Object system.Data.OleDB.OleDbCommand
                $cmd.connection = $conn
                $cmd.commandtext = $query
                Write-Debug $cmd.executenonquery()
                
                Remove-Variable cmd
                
            }
            catch
            {
                if ($cmd) { Remove-Variable cmd }
                Write-Output "'$toInsert' not added to garbage list. Trying the next record."
                continue
            }
        }
    }
    end
    {
        try
        {
            #close database connection
            $conn.Close()
            if ($conn) { Remove-Variable conn }
        }
        catch
        {
            if ($conn) { Remove-Variable conn }
        }
    }
}


function Add-ToSCCM
{
    param
    (
        [parameter(Mandatory = $true)]
        [System.String[]]$addToSCCM
    )
    
    begin
    {
        try
        {
            #open database connection to Access
            $conn = New-Object system.Data.OleDB.OleDbConnection
            $conn.connectionstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$databasePath"
            $conn.Open()
        }
        catch
        {
            if ($conn) { Remove-Variable conn }
            Write-Output "Could not open connection to database. sccmApps list not updated."
            return
        }
    }
    process
    {
        $addToSCCM | ForEach-Object {
            $toInsert = $_
            try
            {
                #define insert query
                $query = "INSERT INTO sccmApps (applicationName) VALUES('$toInsert')"
                
                #create oledb command for insert, update, or delete
                $cmd = New-Object system.Data.OleDB.OleDbCommand
                $cmd.connection = $conn
                $cmd.commandtext = $query
                Write-Debug $cmd.executenonquery()
                
                Remove-Variable cmd
            }
            catch
            {
                if ($cmd) { Remove-Variable cmd }
                Write-Output "'$toInsert' not added to sccmApps list. Trying the next record."
                continue
            }
        }
    }
    end
    {
        try
        {
            #close database connection
            $conn.Close()
            if ($conn) { Remove-Variable conn }
        }
        catch
        {
            if ($conn) { Remove-Variable conn }
        }
    }
}

#>


function Add-RemoteDataToTemp ($computerName, $SCCMApps, $GarbageApps, $temp)
{
    $sccmAppsToInstall = @()
    $manualAppsToInstall = @()
    try
    {
        Set-RPCServices -computerName $computerName
        
        Set-RemoteAccess -computerName $computerName
        
        #$monitorInfo = Get-MonitorInfo $computerName       
        #Add-MonitorInfoToTemp -monitorInfo $monitorInfo -temp $temp
        
        $temp | Add-Member -MemberType 'NoteProperty' -Name Autologon -Value $(Get-isAutologon -computerName $computerName)
        
        $temp | Add-Member -MemberType 'NoteProperty' -Name BCA -Value $(get-isBCA -computerName $computerName)
        
        if ($temp.BCA -eq "Yes")
        {
            $temp | Add-Member -MemberType 'NoteProperty' -Name NewWNum -Value $(Get-NewWNum -computerName $computerName)
        }
                
        $temp | Add-Member -MemberType 'NoteProperty' -Name Description -Value $(Get-LocalComputerDescription -computerName $computerName)
        
        
        $temp | Add-Member -MemberType 'NoteProperty' -Name Model -Value $(Get-Model -computerName $computerName)
        
        
        $temp | Add-Member -MemberType 'NoteProperty' -Name OperatingSystem -Value $(Get-OS -computerName $computerName)
        
        $printers = Get-printerInfo -computerName $computerName
        $printers = $printers | ForEach-Object { $_ + '.\' }
        Write-Debug "Printers: $printers"
        #$temp | Add-Member -MemberType 'NoteProperty' -Name Printers -Value $(Get-printerInfo -computerName $computerName)
        $temp | Add-Member -MemberType 'NoteProperty' -Name Printers -Value $printers
        
        $installedApps = $(Get-Apps -computerName $computerName)
        Write-Debug "InstalledApps= $installedApps"
        
        Get-AppsToInstall -installedApps $installedApps -SCCMApps $SCCMApps -GarbageApps $GarbageApps -sccmAppsToInstall $sccmAppsToInstall -manualAppsToInstall $manualAppsToInstall
        
        Write-Debug "SccmAppsToInstall: $sccmAppsToInstall"
        Write-Debug "ManualAppsToInstall: $manualAppsToInstall"
        
        $temp | Add-Member -MemberType 'NoteProperty' -Name SCCMApps -Value $sccmAppsToInstall
        $temp | Add-Member -MemberType 'NoteProperty' -Name ManualApps -Value $manualAppsToInstall
        
        #$temp | Add-Member -MemberType 'NoteProperty' -Name ManualApps -Value $(Get-manualApps -installedApps $installedApps -Include $Include, -Exclude $GarbageApps)
        
        $IPInfo = Get-IPInfo -computerName $computerName
        switch ($IPInfo.dhcpEnabled)
        {
            $true
            {
                $IPInfo.dhcpEnabled = "Yes"
            }
            $false
            {
                $IPInfo.dhcpEnabled = "No"
            }
            default
            {
                $IPInfo.dhcpEnabled = "Yes"
            }
        }
        if ($IPInfo)
        {
            $temp | Add-Member -MemberType 'NoteProperty' -Name Adapter -Value $IPInfo.Description
            $temp | Add-Member -MemberType 'NoteProperty' -Name MACAddress -Value $IPInfo.macAddress
            $temp | Add-Member -MemberType 'NoteProperty' -Name DHCPEnabled -Value $IPInfo.dhcpEnabled
            $temp | Add-Member -MemberType 'NoteProperty' -Name IPAddress -Value $IPInfo.ipAddress[0]
            $temp | Add-Member -MemberType 'NoteProperty' -Name SubnetMask -Value $IPInfo.IPSubnet[0]
            $temp | Add-Member -MemberType 'NoteProperty' -Name Gateway -Value $IPInfo.DefaultIPGateway[0]
            $temp | Add-Member -MemberType 'NoteProperty' -Name DNSPrimary -Value $IPInfo.dnsServerSearchOrder[0]
            $temp | Add-Member -MemberType 'NoteProperty' -Name DNSSecondary -Value $IPInfo.dnsServerSearchOrder[1]
        }
        else
        {
            $temp | Add-Member -MemberType 'NoteProperty' -Name Adapter -Value "offline"
            $temp | Add-Member -MemberType 'NoteProperty' -Name MACAddress -Value "offline"
            $temp | Add-Member -MemberType 'NoteProperty' -Name DHCPEnabled -Value "offline"
            $temp | Add-Member -MemberType 'NoteProperty' -Name IPAddress -Value "offline"
            $temp | Add-Member -MemberType 'NoteProperty' -Name SubnetMask -Value "offline"
            $temp | Add-Member -MemberType 'NoteProperty' -Name Gateway -Value "offline"
            $temp | Add-Member -MemberType 'NoteProperty' -Name DNSPrimary -Value "offline"
            $temp | Add-Member -MemberType 'NoteProperty' -Name DNSSecondary -Value "offline"
        }
        
        $topConsoleUser = Get-TopConsoleUser -computerName $computerName
        
        $userInfo = Get-UserInfo -topConsoleUser $topConsoleUser
    }
    catch
    {
        Write-Output "Error: $($_.Exception.Message)"
    }
    
    #Add user info to temp
    $temp | Add-Member -MemberType 'NoteProperty' -Name TopConsoleUser -Value $($userInfo.TCU)
    $temp | Add-Member -MemberType 'NoteProperty' -Name TCU_FirstName -Value $($userInfo.FirstName)
    $temp | Add-Member -MemberType 'NoteProperty' -Name TCU_LastName -Value $($userInfo.LastName)
    $temp | Add-Member -MemberType 'NoteProperty' -Name Site -Value $($userInfo.Site)
    $temp | Add-Member -MemberType 'NoteProperty' -Name Department -Value $($userInfo.Department)
    $temp | Add-Member -MemberType 'NoteProperty' -Name JobTitle -Value $($userInfo.JobTitle)
    $temp | Add-Member -MemberType 'NoteProperty' -Name MgrFirstName -Value $($userInfo.MgrFirstName)
    $temp | Add-Member -MemberType 'NoteProperty' -Name MgrLastName -Value $($userInfo.MgrLastName)
    

#Remove-Variable apps
    
}


function Set-RPCServices ($computerName)
{
    Get-Service -ComputerName $computerName -Name RpcLocator | Start-Service
    Get-Service -ComputerName $computerName -Name RpcEptMapper | Start-Service
    Get-Service -ComputerName $computerName -Name DcomLaunch | Start-Service
}


function Set-RemoteAccess ($computerName)
{
    try
    {
            
        if ((Test-WSMan -ComputerName $computerName -ErrorAction 'SilentlyContinue') -eq $null)
        {
            Set-WinRMListener -ComputerName $computerName -ErrorAction SilentlyContinue
            Restart-WinRM -ComputerName $computerName -ErrorAction SilentlyContinue
            Set-WinRMStartup -ComputerName $computerName -ErrorAction SilentlyContinue
            Set-WinRMFirewallRule -ComputerName $computerName -ErrorAction SilentlyContinue
            Restart-WindowsFirewall -ComputerName $computerName -ErrorAction SilentlyContinue
            Write-Output "PSRemoting setup on $computerName"
        }
        else
        {
            Write-Debug "PSRemoting already setup"
        }
    }
        
    catch
    {
        Write-Output "Unable to setup PSRemoting"
    }
}
    
    function Get-OS ($computerName)
{
    $OS = gwmi -Class Win32_OperatingSystem -ComputerName $computerName
    return $OS.Caption
}

function Get-Model ($computerName)
{
    $model = gwmi -Class Win32_ComputerSystem -ComputerName $computerName
    Write-Debug "Model: $($model.Model)"
    
    return $model.Model
}

function Get-UserInfo ($topConsoleUser)
{
    $userInfo = @()
    
    $userData = Get-ADUser -Identity $topConsoleUser -Properties * | select GivenName, Surname, Company, Department, Title, Manager
    $MgrID = $userData.Manager.Split(",")[0]
    $MgrID = $mgrid.Split("=")[1]
    $MgrData = (Get-ADUser -Identity $MgrID | select GivenName, Surname)
    
    $userInfo = New-Object System.Management.Automation.PSObject -Property @{
        
        TCU = $topConsoleUser
        FirstName = $userData.GivenName
        LastName = $userData.Surname
        Site = $userData.Company
        Department = $userData.Department
        JobTitle = $userData.Title
        MgrFirstName = $MgrData.GivenName
        MgrLastName = $MgrData.Surname
        
    }
    
    return $userInfo
}


function Get-TopConsoleUser ($computerName)
{
    $consoleUsers = gwmi -Query "select * from sms_systemconsoleuser" -Namespace "root\cimv2\sms" -ComputerName $computerName | select * | Sort-Object TotalUserConsoleMinutes -Descending
    $topConsoleUser = $consoleUsers[0].SystemConsoleUser
    $topConsoleUser = ($topConsoleUser.Split("\"))[1]
    return $topConsoleUser
    
    Write-Debug "Top User: $topConsoleUser"
}


function create-schemaFinal ($final, [switch]$offline = $false)
{
    if ($offline)
    {
        return @(
        'ComputerName',
        'Model',
        'Autologon',
        'BCA',
        'NewW#',
        'Description',
        'Status',
        'RefreshDate',
        'InstallTech',
        'Building',
        'Floor',
        'Dept',
        'OperatingSystem',
        'Printers',
        "Adapter",
        "MACAddress",
        "DHCPEnabled",
        "IPAddress",
        "SubnetMask",
        "Gateway",
        "dnsPrimary",
        "dnsSecondary",
        'sccmApps',
        'manualApps',
        'Notes',
        'TCU_FirstName',
        'TCU_LastName',
        'Site',
        'JobTitle',
        'Department',
        'MgrFirstName',
        'MgrLastName'
        )
        
    }
    else
    {
        $monitorArray = @()
        
        $monitorCount = 0
        $final | ForEach-Object {
            $current = (($_ | Get-Member | Where-Object { $_.membertype -eq 'noteproperty' }).name |
                Where-Object { $_ -like "Monitor*_Model" }).count - 1
            if ($current -gt $monitorCount) { $monitorCount = $current }
        }
        
        for ($i = 0; $i -le $monitorCount; $i++)
        {
            $monitorArray += "Monitor$($i+1)_Model"
        }
        
        return @(
        'ComputerName',
        'Model',
        'Autologon',
        'BCA',
        'NewW#',
        'Description',
        'Status',
        'RefreshDate',
        'InstallTech',
        'Building',
        'Floor',
        'Dept',
        'OperatingSystem') + $monitorArray + @(
        'Printers',
        "Adapter",
        "MACAddress",
        "DHCPEnabled",
        "IPAddress",
        "SubnetMask",
        "Gateway",
        "dnsPrimary",
        "dnsSecondary",
        'sccmApps',
        'manualApps',
        'Notes',
        'TCU_FirstName',
        'TCU_LastName',
        "Site",
        'Department',
        'JobTitle',
        'MgrFirstName',
        'MgrLastName'
        )
        
        
        
    }
}


<#function add-SccmInfoToTemp ($sccmPhoneBookRecord, $temp)
{
    $schemaSCCM = ($sccmPhoneBookRecord | Get-Member | Where-Object { $_.membertype -eq 'Property' }).name | Where-Object { $_ -ne 'ComputerName' }
    $schemaSCCM | ForEach-Object {
        $value = $_
        $temp | Add-Member -MemberType 'NoteProperty' -Name $value -Value $sccmPhoneBookRecord."$value"
    }
}
#>

function Add-MonitorInfoToTemp ($monitorInfo, $temp)
{
    for ($i = 0; $i -lt 2; $i++)
    {
        Write-Debug "Monitor$($i + 1)=$monitor[$i].Model"
        $temp | Add-Member -MemberType 'NoteProperty' -Name "Monitor$($i + 1)_Model" -Value $monitorInfo[$i].Model
    }
        
}


function test-databaseRead
{
    # test database read
    #if error and x64 open x86 powershell
    try
    {
        $conn = New-Object system.Data.OleDB.OleDbConnection
        $conn.connectionstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$databasePath"
        $conn.Open()
        $conn.Close()
        &"$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe" -executionPolicy 'unrestricted' -file "$sd\$name" -noexit
    }
    catch
    {
        function Get-ScriptDirectory
        {
        <#
            .SYNOPSIS
                Get-ScriptDirectory returns the proper location of the script.
        
            .OUTPUTS
                System.String
            
            .NOTES
                Returns the correct path within a packaged executable.
        #>
            [OutputType([string])]
            param ()
            if ($hostinvocation -ne $null)
            {
                Split-Path $hostinvocation.MyCommand.Path
            }
            else
            {
                Split-Path $script:MyInvocation.MyCommand.Path
            }
        }
        
        function Get-ScriptName
        {
        <#
            .SYNOPSIS
                Get-ScriptName returns the name of the script.

            .OUTPUTS
                System.String
                
            .NOTES
                Returns the correct name within a packaged executable.
        #>
            [OutputType([string])]
            param ()
            if ($hostinvocation -ne $null)
            {
                $hostinvocation.MyCommand.name
            }
            else
            {
                $script:MyInvocation.MyCommand.name
            }
        }
        
        
        if ($env:PROCESSOR_ARCHITECTURE -eq 'AMD64')
        {
            $sd = Get-scriptdirectory
            $name = Get-ScriptName
            &"$env:windir\SysWOW64\WindowsPowerShell\v1.0\powershell.exe" -executionPolicy 'unrestricted' -file "$sd\$name" -noexit
            #exit
        }
        else { exit }
    }
}



function Query-wNumberDBdev_Garbage
{
    $results = @()
    
    #Database Query
    $QueryString = "select applicationName from Garbage"
    #Database Connection String
    $ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$databasePath"
    $conn = New-Object System.Data.OleDb.OleDbConnection ($ConnectionString)
    #$conn.connectionstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$databasePath"
    $conn.Open()
    if ($conn.State -eq [System.Data.ConnectionState]::Open)
    {
        $command = New-Object System.Data.OleDb.OleDbCommand ($QueryString, $conn)
        $StringBuilder = New-Object System.Text.StringBuilder
        #Run the query
        $recordset = $command.ExecuteReader()
        While ($recordset.Read() -eq $true)
        {
            #Clear the StringBuilder
            [void]$StringBuilder.Remove(0, $StringBuilder.Length)
            
            #Loop through each field
            for ($index = 0; $index -lt $recordset.FieldCount; $index++)
            {
                if ($index -ne 0)
                {
                    [void]$StringBuilder.Append(", ")
                }
                [void]$StringBuilder.Append($recordset.GetValue($index).ToString())
            }
            #Output the Row
            $results += $StringBuilder.ToString()
        }
        #Close the Connection
        $recordset.Close()
        $conn.Close()
    }
    
    return $results
}







function Query-wNumberDBdev_sccmApps
{
    $results = @()
    
    #Database Query
    $QueryString = "select applicationName from sccmApps"
    
    #Database Connection String
    
    $ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$databasePath"
    $connection = New-Object System.Data.OleDb.OleDbConnection ($ConnectionString)
    $connection.Open()
    if ($connection.State -eq [System.Data.ConnectionState]::Open)
    {
        $command = New-Object System.Data.OleDb.OleDbCommand ($QueryString, $connection)
        $StringBuilder = New-Object System.Text.StringBuilder
        #Run the query
        $recordset = $command.ExecuteReader()
        While ($recordset.Read() -eq $true)
        {
            #Clear the StringBuilder
            [void]$StringBuilder.Remove(0, $StringBuilder.Length)
            
            #Loop through each field
            for ($index = 0; $index -lt $recordset.FieldCount; $index++)
            {
                if ($index -ne 0)
                {
                    [void]$StringBuilder.Append(", ")
                }
                [void]$StringBuilder.Append($recordset.GetValue($index).ToString())
            }
            #Output the Row
            $results += $StringBuilder.ToString()
        }
        #Close the Connection
        $recordset.Close()
        $connection.Close()
    }
    return $results
}

Function Get-MonitorInfo ($computerName)
{
    try
    {
        
        $monitors = gwmi -Class WmiMonitorID -Namespace 'root\wmi' -computername $computerName | Select @{ n = "Model"; e = { [System.Text.Encoding]::ASCII.GetString($_.UserFriendlyName -ne 00) } }
        
        Write-Debug "monitors=$($monitors.Model)"
        return $monitors
        
        
    }
    
    catch
    {
        Write-Debug Exception.Message
    }
}

function Get-isAutologon ($computerName)
{
    $ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
    try
    {
        $sb = [scriptblock]::create("Get-Service -computername '$computerName' -Name RemoteRegistry")
        $job = Start-Job -ScriptBlock $sb | Wait-Job -Timeout 30
        if ($job.state -ne 'Completed')
        {
            throw 'timed out'
        }
        else { $service = Receive-Job $job }
        
        if ($service.Status -eq "Running")
        {
            $remoteRegBaseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computerName)
            $remoteRegSubKey = $remoteRegBaseKey.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", $false)
            $isAutologon = $remoteRegSubKey.GetValue("AutoAdminLogon")
        }
        else
        {
            throw 'not running'
        }
    }
    catch { $isAutologon = $null }
    
    switch ($isAutologon)
    {
        $null
        {
            $isAutologon = "No"
            #Write-Debug "isAutologon=$isAutologon"
        }
        
        0
        {
            $isAutologon = "No"
            #Write-Debug "isAutologon=$isAutologon"
        }
        
        1
        {
            $isAutologon = "Yes"
            #Write-Debug "isAutologon=$isAutologon"
        }
        
        default
        {
            $isAutologon = "No"
        }
    }
    Write-Debug "isAutologon=$isAutologon"
    return $isAutologon
}

function get-isBCA ($computerName)
{
    $sb = [scriptblock]::create("Get-Process -ComputerName '$computerName'")
    $job = Start-Job -ScriptBlock $sb | Wait-Job -Timeout 30
    if ($job.state -ne 'Completed')
    {
        $isBCA = "No"
    }
    else
    {
        $process = Receive-Job $job
        $process = $process | Where-Object { $_.processName -eq 'EpicPrintService' }
    }
    if ($process) { $isBCA = "Yes" }
    else { $isBCA = "No" }
    
    Write-Debug "isBCA=$isBCA"
    return $isBCA
}

function Get-NewWNum ($computerName)
{
    if ($computerName -notcontains "BCA")
    {
        $NewWNum = $($computerName + "BCA")
        Write-Debug "NewWNum=$NewWNum"
    }
    return $NewWNum
}

function Get-LocalComputerDescription ($computerName)
{
    $Description = gwmi -Class Win32_OperatingSystem -ComputerName $computerName -ErrorAction 'Stop'
    Write-Debug "$($computerName): localComputerDescription= $($Description.Description)"
    return $Description.Description
}


function Get-printerInfo ($computerName)
{
    $printers = @()
    try
    {
        $printers = gwmi Win32_Printer -ComputerName $computerName -Filter "Name like '%secvpsx%'" | Sort-Object Default -Descending 
        #$printerList = ($printers | ForEach-Object {($_.PortName + '.\')})
        Write-Debug "Printers= $($printers.PortName)"
    }
    
    catch
    {
        Write-Debug "Error: $_.Exception.Message"
    }
    
    return $printers.PortName
}




function Get-Apps ($computerName)
{
    #$programList = @()
    $programList = gwmi Win32Reg_AddRemovePrograms -ComputerName $computerName | Sort-Object { $_.DisplayName } 
    #$programList = $programList | ForEach-Object {$_.DisplayName + '.\' }
    
    return $programList.DisplayName
}


function Get-sccmApps ($installedApps, $Includes)
{
    try
    {
        #Write-Debug "InstalledApps=$installedApps"
        
        $sccmApps = @()
        foreach ($installedApp in $installedApps)
        {
            foreach ($Include in $Includes)
            {
                Write-Debug "InstalledApp=$installedApp"
                Write-Debug "ReferenceApp=$Include"
                if (Compare-Object $installedApp.trim() $Include.trim() -IncludeEqual -ExcludeDifferent)
                #if ($installedApp.trim() -like $Include.trim())
                {
                    $sccmApps += $installedApp.trim()
                    #$sccmApps += $app
                }
            }
        }
        
        #$appComparison = Compare-Object $installedApps $Includes -ExcludeDifferent -IncludeEqual
        #Write-Debug "Installed apps= $appComparison"
        Write-Debug "sccmApps=$sccmApps"
        $sccmApps = ($sccmApps | Sort-Object) -join "\\"
    }
    catch
    {
        $sccmApps = $null
        Write-Debug $_.Exception.Message
    }
    return $sccmApps
}


function Get-AppsToInstall ($installedApps, $SCCMapps, $GarbageApps, $sccmAppsToInstall, $manualAppsToInstall)
{
    $installedApps | ForEach-Object {
        $currentApp = $_
        if (Compare-Object -ReferenceObject $currentApp -DifferenceObject $SCCMapps -IncludeEqual -ExcludeDifferent)
        {
            $sccmAppsToInstall += $currentApp #in master SCCM app list
        }
        else
        {
            if (!(Compare-Object $currentApp $GarbageApps -IncludeEqual -ExcludeDifferent))
            {
                $manualAppsToInstall += $currentApp  #NOT in master Garbage app list
            }
        }
    }
    
}


function Get-manualApps ($installedApps, $Include, $Exclude)
{
    try
    {
        Write-Debug "Installed Apps=$installedApps"
        #$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
        $manualApps = @()
        foreach ($installedApp in $installedApps)
        {
            if (!(Compare-Object $installedApp.trim() $Include -IncludeEqual -ExcludeDifferent))    #compare apps to SCCM app list
            #if ($installedApp.trim() -notlike $Include)
            {
                if (!(Compare-Object $installedApp.trim() $Exclude -IncludeEqual -ExcludeDifferent))    #compare apps to Garbage app list
                #if ($installedApp.trim() -notlike $Exclude)
                {                   
                    $manualApps += $installedApp.trim()         #Not a match - add to Manual app list
                    
                }
            }
        }
        Write-Debug "manualApps=$manualApps"
        $manualApps = ($manualApps | Sort-Object) -join "\\"
    }
    catch { $manualApps = $null }
    return $manualApps
}








function export-xls
{
<#
.SYNOPSIS
Export to Excel file.

.DESCRIPTION
Export to Excel file. Since Excel files can have multiple worksheets, you can specify the name of the Excel file and worksheet. Exports to a worksheet named "Sheet" by default.

.PARAMETER Path
Specifies the path to the Excel file to export.
Note: The path must contain an extension for spreadsheets, such as .xls, .xlsx, .xlsm, .xml, and .ods

.PARAMETER Worksheet
Specifies the name of the worksheet where the data is exported. The default is "Sheet".
Note: If a worksheet already exists with the given name, no error occurs. The name will be appended with (2), or (3), or (4), etc.

.PARAMETER InputObject
Specifies the objects to export. You can also pipe objects to Export-Xls.

.PARAMETER Append
Append the exported data to a new worksheet in the excel file.
If you Append to a spreadsheet that does not allow more than one worksheet, the new data will not be saved.
Note: For this function, -Append is not considered clobbering the file, but modifying the file, so -Append and -NoClobber do not conflict with each other.

.PARAMETER NoClobber
Do not overwrite the file.
Use -Append if you want to add a worksheet to the excel file, but leave the others intact.
Note: For this function, -Append is not considered clobbering the file, but modifying the file, so -Append and -NoClobber do not conflict with each other.

.PARAMETER NoTypeInformation
Omits the type information.

.INPUTS
System.Management.Automation.PSObject

.OUTPUTS
System.String
This is a CSV list, which is then exported to a csv file, which is then converted to an Excel file.

.EXAMPLE
Get-Process | Export-Xls ".\export.xlsx" -Worksheet "Sheet1"
Export the output of Get-Process to Worksheet "Sheet1" of export.xlsx
Note: export.xlsx is overwritten.

.EXAMPLE
Get-Process | Export-Xls ".\export.xlsx" -Worksheet "Sheet2" -NoTypeInformation
Export the output of Get-Process to Worksheet "Sheet2" of export.xlsx with no type information
Note: export.xlsx is overwritten.

.EXAMPLE
Get-Process | Export-Xls ".\export.xlsx" -Worksheet "Sheet3" -Append
Export output of Get-Process to Worksheet "Sheet3" and Append it to export.xlsx
Note: export.xlsx is modified.

.EXAMPLE
Get-Process | Export-Xls ".\export.xlsx" -Worksheet "Sheet4" -NoClobber
Export output of Get-Process to Worksheet "Sheet4" and create export.xlsx if it doesn't exist.
Note: export.xlsx is created. If export.xlsx already exist, the function terminates with an error.

.EXAMPLE
(Get-Alias s*), (Get-Alias g*) | Export-Xls ".\export.xlsx" -Worksheet "Alias"
Export Aliases that start with s and g to Worksheet "Alias" of export.xlsx
Note: See next example for possible problems when doing something like this

.EXAMPLE
(Get-Alias), (Get-Process) | Export-Xls ".\export.xlsx" -Worksheet "Alias and Process"
Export the result of Get-Command and Get-Process to Worksheet "Alias and Process" of export.xlsx
Note: Since Get-Alias and Get-Process do not return objects with the same properties, not all information is recorded.

.LINK
Export-Xls
http://gallery.technet.microsoft.com/scriptcenter/d41565f1-37ef-43cb-9462-a08cd5a610e2
Import-Xls
http://gallery.technet.microsoft.com/scriptcenter/17bcabe7-322a-43d3-9a27-f3f96618c74b
Import-Csv
Export-Csv

.NOTES
Author: Francis de la Cerna
Created: 2011-03-27
Modified: 2011-04-09
#Requires –Version 2.0

taken from https://gallery.technet.microsoft.com/office/d41565f1-37ef-43cb-9462-a08cd5a610e2
#>
    
    [CmdletBinding(SupportsShouldProcess = $true)]
    Param (
        [parameter(mandatory = $true, position = 1)]
        $Path,
        [parameter(mandatory = $false, position = 2)]
        $Worksheet = "Sheet",
        [parameter(
                   mandatory = $true,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true)]
        [psobject[]]
        $InputObject,
        [parameter(mandatory = $false)]
        [switch]$Append,
        [parameter(mandatory = $false)]
        [switch]$NoClobber,
        [parameter(mandatory = $false)]
        [switch]$NoTypeInformation,
        [parameter(mandatory = $false)]
        [switch]$Force
    )
    
    Begin
    {
        # WhatIf, Confirm, Verbose
        # Probably not the way to do it, but this function runs all or nothing
        # so, exit each block (Begin, Process, End) if shouldProcesss is false.
        # Disabled confirmations on operations on temporary files, but enabled
        # verbose messages.
        #
        $shouldProcess = $Force -or $psCmdlet.ShouldProcess($Path);
        
        if (-not $shouldProcess) { return; }
        
        function GetTempFileName($extension)
        {
            $temp = [io.path]::GetTempFileName();
            $params = @{
                Path = $temp;
                Destination = $temp + $extension;
                Confirm = $false;
                Verbose = $VerbosePreference;
            }
            Move-Item @params;
            $temp += $extension;
            return $temp;
        }
        
        # check extension of $Path to see what excel format to export to
        # since an extension like .xls can have multiple formats, this
        # will need to be changed
        #
        $xlFileFormats = @{
            # single worksheet formats
            '.csv' = 6; # 6, 22, 23, 24
            '.dbf' = 11; # 7, 8, 11
            '.dif' = 9; #
            '.prn' = 36; #
            '.slk' = 2; # 2, 10
            '.wk1' = 31; # 5, 30, 31
            '.wk3' = 32; # 15, 32
            '.wk4' = 38; #
            '.wks' = 4; #
            '.xlw' = 35; #
            
            # multiple worksheet formats
            '.xls' = -4143; # -4143, 1, 16, 18, 29, 33, 39, 43
            '.xlsb' = 50; #
            '.xlsm' = 52; #
            '.xlsx' = 51; #
            '.xml' = 46; #
            '.ods' = 60; #
        }
        
        $ext = [io.path]::GetExtension($Path).toLower();
        if ($xlFileFormats.Keys -notcontains $ext)
        {
            $msg = "Error: $Path has unknown extension. Try ";
            foreach ($extension in ($xlFileFormats.Keys | Sort-Object))
            {
                $msg += "$extension ";
            }
            Throw "$msg";
        }
        
        # get full path
        #
        if (-not [io.path]::IsPathRooted($Path))
        {
            $fswd = $psCmdlet.CurrentProviderLocation("FileSystem");
            $Path = Join-Path -Path $fswd -ChildPath $Path;
        }
        
        $Path = [io.path]::GetFullPath($Path);
        
        $obj = New-Object System.Collections.ArrayList;
    }
    
    Process
    {
        if (-not $shouldProcess) { return; }
        
        $InputObject | ForEach-Object{ $obj.Add($_) | Out-Null; }
    }
    
    End
    {
        if (-not $shouldProcess) { return; }
        
        $xl = New-Object -ComObject Excel.Application;
        $xl.DisplayAlerts = $false;
        $xl.Visible = $false;
        
        # create temporary .csv file from all $InputObject
        #
        $csvTemp = GetTempFileName(".csv");
        $obj | Export-Csv -Path $csvTemp -Force -NoTypeInformation:$NoTypeInformation -Confirm:$false;
        
        # create a temporary excel file from the temporary .csv file
        #
        $xlsTemp = GetTempFileName($ext);
        $wb = $xl.Workbooks.Add($csvTemp);
        $ws = $wb.Worksheets.Item(1);
        $ws.Name = $Worksheet;
        $wb.SaveAs($xlsTemp, $xlFileFormats[$ext]);
        $xlsTempSaved = $?;
        $wb.Close();
        Remove-Variable -Name ('ws', 'wb') -Confirm:$false;
        
        if ($xlsTempSaved)
        {
            # decide how to export based on switches and $Path
            #
            $fileExist = Test-Path $Path;
            $createFile = -not $fileExist;
            $appendFile = $fileExist -and $Append;
            $clobberFile = $fileExist -and (-not $appendFile) -and (-not $NoClobber);
            $needNewFile = $fileExist -and (-not $appendFile) -and $NoClobber;
            
            if ($appendFile)
            {
                $wbDst = $xl.Workbooks.Open($Path);
                $wbSrc = $xl.Workbooks.Open($xlsTemp);
                $wsDst = $wbDst.Worksheets.Item($wbDst.Worksheets.Count);
                $wsSrc = $wbSrc.Worksheets.Item(1);
                $wsSrc.Name = $Worksheet;
                $wsSrc.Copy($wsDst);
                $wsDst.Move($wbDst.Worksheets.Item($wbDst.Worksheets.Count - 1));
                $wbDst.Worksheets.Item(1).Select();
                $wbSrc.Close($false);
                $wbDst.Close($true);
                Remove-Variable -Name ('wsSrc', 'wbSrc') -Confirm:$false;
                Remove-Variable -Name ('wsDst', 'wbDst') -Confirm:$false;
            }
            elseif ($createFile -or $clobberFile)
            {
                Copy-Item $xlsTemp -Destination $Path -Force -Confirm:$false;
            }
            elseif ($needNewFile)
            {
                Write-Error "The file '$Path' already exists." -Category ResourceExists;
            }
            else
            {
                Write-Error "Something was wrong with my logic.";
            }
        }
        
        # clean up
        #
        $xl.Quit();
        Remove-Variable -name xl -Confirm:$false;
        Remove-Item $xlsTemp -Confirm:$false -Verbose:$VerbosePreference;
        Remove-Item $csvTemp -Confirm:$false -Verbose:$VerbosePreference;
        [gc]::Collect();
    }
}









#SCRIPT ENTRY POINT############################
main
###############################################

Tuesday, November 15, 2016 8:34 PM

As I posted ab0ve - you have functions inside of functions.  Why?

"Main" is a function. Any variables created in main will not exist outside of Main.

Remember this is not a compiled program.  There is really no need for a "Main". 

If you want variables to be visible anywhere declare them before calling main or make them "global" variables.

Normally we pass variables t functions and return results from a function.

What I can pick out shows you are getting the contents of a file and passing it as a parameter.  There is no issue with this.  I cannot see what your problem is.  What is the error?

\(ツ)_/


Tuesday, November 15, 2016 9:02 PM

The only thing I get is a null value for $SCCMApps. It is not null right before I call Get-AppsToIinstall but once it gets inside the function, it is null. Not a clue as to why it did that. I did not create this script; I am merely maintaining it and modifying it because it was poorly written IMO. How would I get rid of main in this case? Would I just put the code in main into a new function that runs first?


Tuesday, November 15, 2016 9:03 PM

As I posted ab0ve - you have functions inside of functions.  Why?

"Main" is a function. Any variables created in main will not exist outside of Main.

Remember this is not a compiled program.  There is really no need for a "Main". 

If you want variables to be visible anywhere declare them before calling main or make them "global" variables.

Normally we pass variables t functions and return results from a function.

What I can pick out shows you are getting the contents of a file and passing it as a parameter.  There is no issue with this.  I cannot see what your problem is.  What is the error?

\(ツ)_/

I don't agree that variables don't exist outside of main. I use 5 different variables as parameters of the Get-AppsToInstall function and all but 1 of them is not null.


Tuesday, November 15, 2016 9:07 PM

It works as expected for the rest of us so you are missing some piece of information.

function main{
    $Myvar = 'Test'
    Other-Function $myvar
}
function Other-Function($passed){
    Write-Host $passed -fore green
}

main

\(ツ)_/


Tuesday, November 15, 2016 9:09 PM

You are calling a job but never passing the variable to the job.  You have to explicitly pass the variable.

help Start-Job -full

\(ツ)_/


Tuesday, November 15, 2016 9:12 PM

As I posted ab0ve - you have functions inside of functions.  Why?

"Main" is a function. Any variables created in main will not exist outside of Main.

Remember this is not a compiled program.  There is really no need for a "Main". 

If you want variables to be visible anywhere declare them before calling main or make them "global" variables.

Normally we pass variables t functions and return results from a function.

What I can pick out shows you are getting the contents of a file and passing it as a parameter.  There is no issue with this.  I cannot see what your problem is.  What is the error?

\(ツ)_/

I don't agree that variables don't exist outside of main. I use 5 different variables as parameters of the Get-AppsToInstall function and all but 1 of them is not null.

Rather than my trying to debate this with you I recommend that you read the documentation to understand how this works:

help about_scopes

Part of the issue is your mixing arguments, parameters and variables.  They all refer to different things and you are calling all of them "variables".\

\(ツ)_/


Tuesday, November 15, 2016 9:36 PM

Sorry for the arguments. I changed the 3 "variable" names to $global, but it is still doing the same thing. The $SCCMApps var is non-null right before I call Add-RemoteDataToTemp but once it gets inside that function, the $SCCMApps is null. Not a clue what is going on. I thought I understood Scope and I've been passing parameters through so many of my scripts and never had a problem before now. I'm at a loss. I just want to compare the apps installed on a system to a master list of apps so I can determine if they are apps that are available in our SCCM push.


Tuesday, November 15, 2016 9:45 PM

Sorry for the arguments. I changed the 3 "variable" names to $global, but it is still doing the same thing. The $SCCMApps var is non-null right before I call Add-RemoteDataToTemp but once it gets inside that function, the $SCCMApps is null. Not a clue what is going on. I thought I understood Scope and I've been passing parameters through so many of my scripts and never had a problem before now. I'm at a loss. I just want to compare the apps installed on a system to a master list of apps so I can determine if they are apps that are available in our SCCM push.

A "job" has no access to global variables defined in the calling script.  A "job" runs in a separate memory space as a full copy of PowerShell and can only get information from passed arguments or from the system.

This is your call:

Add-RemoteDataToTemp -computerName $computerName -SSCMApps $SCCMApps -GarbageApps $GarbageApps -temp $temp

And this is your catch

function Add-RemoteDataToTemp{
** Param(**
**  $computerName,**
**  $SCCMApps,**
**  $GarbageApps,**
**  $temp**
** )**

If you use the "Param" syntax it will give you more information.

You can see that you have a misspelling.

\(ツ)_/


Tuesday, November 15, 2016 9:47 PM

To be more explicit look at this:

 -SSCMApps $SCCMApps

Before anything else fix the spelling.

\(ツ)_/


Tuesday, November 15, 2016 9:50 PM

Holy F**K! I knew it had to be something so lame.


Tuesday, November 15, 2016 9:53 PM

Mark britehere's post as he saw it first.

This is an issue with over commenting and leaving old code behind.  It makes seeing things harder. Also assuming the worst was misleading to all of us.

\(ツ)_/