?
Solved

Why doesn't the PowerShell, cmdletbinding, command work incorrectly?

Posted on 2015-02-03
3
Medium Priority
?
553 Views
Last Modified: 2015-02-03
Hello Expert,

When I test this script the cmdletbinding command and all the contents fail, why? File DesktopComputers.txt has only one entry, my computer name with the domain name (ex. curiousMAuser.company.local)

What value do these parameters have? 'ValueFromPipeline' and 'ValueFromPipelineByPropertyValue' are not defined?
[Parameter( ValueFromPipeline=$true,
 ValueFromPipelineByPropertyName=$true

Thank you,
CuriousMAUser

 =========================================================================================
#
# NAME: Ref48Step1GetRemoteGroupMembers.ps1
#
# Modified: IT Staff
# Date: 03-Feb-2015
# Verison: PowerShell 4.0
# Client OS: Windows 7, Server OS: Windows 2008 R2
#
# DESCRIPTION:
# Supply this function with an Active Directory local groups members
#
# Assumes the presence of Microsoft's ActiveDirectory PowerShell module.
# ==============================================================================================
<#
 .Synopsis
  Gets membership information of remote computer groups

 .Description
  This script by default queries the membership details of local administrators group on remote computers
  It has a provision to query any local group in remote server, not just administrators group
 
 .Parameter ComputerName - $ComputerName = $env:ComputerName
  Computer Name(s) which you want to query for local group information
 
 .Parameter RemoteGroupName - $RemoteGroupName = "Administrators",
  Name of the remote group which you want to query for membership information. It queries 'Administrators' group when
  this parameter is not specified
 
 .Parameter OutputDir - $OutputDir = "c:\Scripts"
  Name of the folder where you want to place the output file. It creates the output file in c:\Scripts folder.
 
 .Example - option 1
  Ref48Step1GetRemoteGroupMembers.ps1
  Queries the local administrators group membership and writes the details to c:\Scripts\RemoteGroupMembers.CSV
 
 .Example - option 2
  Ref48Step1GetRemoteGroupMembers.ps1 -ComputerName (Get-Content c:\Scripts\DesktopComputers.txt)
 
 .Example - option 3
  Ref48Step1GetRemoteGroupMembers.ps1 -ComputerName Desktop01, Desktop02
#>

Set-ExecutionPolicy remotesigned -Force
Import-Module activedirectory

[CmdletBinding()]
Param(
 [Parameter( ValueFromPipeline=$true,
 ValueFromPipelineByPropertyName=$true
 )]
 [string[]] $ComputerName = "Get-Content c:\Scripts\DesktopComputers.txt",
 
 [Parameter()]
 [string] $RemoteGroupName = "Administrators",
 
 [Parameter()]
 [string] $OutputDir = "c:\Scripts"
)
 
Begin {
 
 $OutputFile = Join-Path $OutputDir "RemoteGroupMembers.csv"
 Write-Verbose "Script will write the output to $OutputFile folder"
 Add-Content -Path $OutPutFile -Value "ComputerName, RemoteGroupName, Status, MemberType, MemberDomain, MemberName"
}
 
Process {
 ForEach($Computer in $ComputerName) {
 Write-host "Working on $Computer"
 If(!(Test-Connection -ComputerName $Computer -Count 1 -Quiet)) {
 Write-Verbose "$Computer is offline. Proceeding with next computer"
 Add-Content -Path $OutputFile -Value "$Computer,$RemoteGroupName,Offline"
 Continue
 } else {
 Write-Verbose "Working on $computer"
 try {
 $group = [ADSI]"WinNT://$Computer/$RemoteGroupName"
 $members = @($group.Invoke("Members"))
 Write-Verbose "Successfully queries the members of $computer"
 if(!$members) {
 Add-Content -Path $OutputFile -Value "$Computer,$RemoteGroupName,NoMembersFound"
 Write-Verbose "No members found in the group"
 continue
 }
 }
 catch {
 Write-Verbose "Failed to query the members of $computer"
 Add-Content -Path $OutputFile -Value "$Computer,,FailedToQuery"
 Continue
 }
 foreach($member in $members) {
 try {
 $MemberName = $member.GetType().Invokemember("Name","GetProperty",$null,$member,$null)
 $MemberType = $member.GetType().Invokemember("Class","GetProperty",$null,$member,$null)
 $MemberPath = $member.GetType().Invokemember("ADSPath","GetProperty",$null,$member,$null)
 $MemberDomain = $null
 if($MemberPath -match "^Winnt\:\/\/(?<domainName>\S+)\/(?<CompName>\S+)\/") {
 if($MemberType -eq "User") {
 $MemberType = "RemoteUser"
 } elseif($MemberType -eq "Group"){
 $MemberType = "RemoteGroup"
 }
 $MemberDomain = $matches["CompName"]
 
 } elseif($MemberPath -match "^WinNT\:\/\/(?<domainname>\S+)/") {
 if($MemberType -eq "User") {
 $MemberType = "DomainUser"
 } elseif($MemberType -eq "Group"){
 $MemberType = "DomainGroup"
 }
 $MemberDomain = $matches["domainname"]
 
 } else {
 $MemberType = "Unknown"
 $MemberDomain = "Unknown"
 }
 Add-Content -Path $OutPutFile -Value "$Computer, $RemoteGroupName, SUCCESS, $MemberType, $MemberDomain, $MemberName"
 } catch {
 Write-Verbose "failed to query details of a member. Details $_"
 Add-Content -Path $OutputFile -Value "$Computer,,FailedQueryMember"
 }
 
 }
 }
 
 }
 
}
End {}
0
Comment
Question by:CuriousMAUser
3 Comments
 
LVL 40

Accepted Solution

by:
Subsun earned 2000 total points
ID: 40586508
Make It as the first line of code.. Move Import-Module activedirectory  to begin block and try..
#=========================================================================================
 # 
 # NAME: Ref48Step1GetRemoteGroupMembers.ps1
 #
 # Modified: IT Staff
 # Date: 03-Feb-2015
 # Verison: PowerShell 4.0
 # Client OS: Windows 7, Server OS: Windows 2008 R2 
 #
 # DESCRIPTION: 
 # Supply this function with an Active Directory local groups members
 #
 # Assumes the presence of Microsoft's ActiveDirectory PowerShell module.
 # ==============================================================================================
 <#
  .Synopsis 
   Gets membership information of remote computer groups

  .Description
   This script by default queries the membership details of local administrators group on remote computers
   It has a provision to query any local group in remote server, not just administrators group 
  
  .Parameter ComputerName - $ComputerName = $env:ComputerName
   Computer Name(s) which you want to query for local group information
  
  .Parameter RemoteGroupName - $RemoteGroupName = "Administrators",
   Name of the remote group which you want to query for membership information. It queries 'Administrators' group when
   this parameter is not specified
  
  .Parameter OutputDir - $OutputDir = "c:\Scripts"
   Name of the folder where you want to place the output file. It creates the output file in c:\Scripts folder.
  
  .Example - option 1
   Ref48Step1GetRemoteGroupMembers.ps1
   Queries the local administrators group membership and writes the details to c:\Scripts\RemoteGroupMembers.CSV
  
  .Example - option 2
   Ref48Step1GetRemoteGroupMembers.ps1 -ComputerName (Get-Content c:\Scripts\DesktopComputers.txt)
  
  .Example - option 3
   Ref48Step1GetRemoteGroupMembers.ps1 -ComputerName Desktop01, Desktop02
 #>

[CmdletBinding()]
 Param(
  [Parameter( ValueFromPipeline=$true,
  ValueFromPipelineByPropertyName=$true
  )]
  [string[]] $ComputerName = "Get-Content c:\Scripts\DesktopComputers.txt",
  
  [Parameter()] 
  [string] $RemoteGroupName = "Administrators",
  
  [Parameter()]
  [string] $OutputDir = "c:\Scripts"
 )
  
 Begin {
  Import-Module activedirectory 
  $OutputFile = Join-Path $OutputDir "RemoteGroupMembers.csv"
  Write-Verbose "Script will write the output to $OutputFile folder"
  Add-Content -Path $OutPutFile -Value "ComputerName, RemoteGroupName, Status, MemberType, MemberDomain, MemberName"
 }
  
 Process {
  ForEach($Computer in $ComputerName) {
  Write-host "Working on $Computer"
  If(!(Test-Connection -ComputerName $Computer -Count 1 -Quiet)) {
  Write-Verbose "$Computer is offline. Proceeding with next computer"
  Add-Content -Path $OutputFile -Value "$Computer,$RemoteGroupName,Offline"
  Continue
  } else {
  Write-Verbose "Working on $computer"
  try {
  $group = [ADSI]"WinNT://$Computer/$RemoteGroupName"
  $members = @($group.Invoke("Members"))
  Write-Verbose "Successfully queries the members of $computer"
  if(!$members) {
  Add-Content -Path $OutputFile -Value "$Computer,$RemoteGroupName,NoMembersFound"
  Write-Verbose "No members found in the group"
  continue
  }
  } 
  catch {
  Write-Verbose "Failed to query the members of $computer"
  Add-Content -Path $OutputFile -Value "$Computer,,FailedToQuery"
  Continue
  }
  foreach($member in $members) {
  try {
  $MemberName = $member.GetType().Invokemember("Name","GetProperty",$null,$member,$null)
  $MemberType = $member.GetType().Invokemember("Class","GetProperty",$null,$member,$null)
  $MemberPath = $member.GetType().Invokemember("ADSPath","GetProperty",$null,$member,$null)
  $MemberDomain = $null
  if($MemberPath -match "^Winnt\:\/\/(?<domainName>\S+)\/(?<CompName>\S+)\/") {
  if($MemberType -eq "User") {
  $MemberType = "RemoteUser"
  } elseif($MemberType -eq "Group"){
  $MemberType = "RemoteGroup"
  }
  $MemberDomain = $matches["CompName"]
  
  } elseif($MemberPath -match "^WinNT\:\/\/(?<domainname>\S+)/") {
  if($MemberType -eq "User") {
  $MemberType = "DomainUser"
  } elseif($MemberType -eq "Group"){
  $MemberType = "DomainGroup"
  }
  $MemberDomain = $matches["domainname"]
  
  } else {
  $MemberType = "Unknown"
  $MemberDomain = "Unknown"
  }
  Add-Content -Path $OutPutFile -Value "$Computer, $RemoteGroupName, SUCCESS, $MemberType, $MemberDomain, $MemberName"
  } catch {
  Write-Verbose "failed to query details of a member. Details $_"
  Add-Content -Path $OutputFile -Value "$Computer,,FailedQueryMember"
  }
  
  } 
  }
  
  }
  
 }
 End {} 

Open in new window

0
 

Author Closing Comment

by:CuriousMAUser
ID: 40586551
Thank you. The simple adjustment worked. Script works correctly now.
0
 
LVL 85

Expert Comment

by:David Johnson, CD, MVP
ID: 40586627
cmdletbinding requires that it be in a function.
The CmdletBinding attribute is an attribute of functions that makes them operate like compiled cmdlets
get-help about_Functions_CmdletBindingAttribute
#
# NAME: Ref48Step1GetRemoteGroupMembers.ps1
#
# Modified: IT Staff
# Date: 03-Feb-2015
#Requires -Version 4.0
# Client OS: Windows 7, Server OS: Windows 2008 R2
#
# DESCRIPTION:
# Supply this function with an Active Directory local groups members
#
# Assumes the presence of Microsoft's ActiveDirectory PowerShell module.
# ==============================================================================================
<#
 .Synopsis
  Gets membership information of remote computer groups

 .Description
  This script by default queries the membership details of local administrators group on remote computers
  It has a provision to query any local group in remote server, not just administrators group
 
 .Parameter ComputerName - $ComputerName = $env:ComputerName
  Computer Name(s) which you want to query for local group information
 
 .Parameter RemoteGroupName - $RemoteGroupName = "Administrators",
  Name of the remote group which you want to query for membership information. It queries 'Administrators' group when
  this parameter is not specified
 
 .Parameter OutputDir - $OutputDir = "c:\Scripts"
  Name of the folder where you want to place the output file. It creates the output file in c:\Scripts folder.
 
 .Example - option 1
  Ref48Step1GetRemoteGroupMembers.ps1
  Queries the local administrators group membership and writes the details to c:\Scripts\RemoteGroupMembers.CSV
 
 .Example - option 2
  Ref48Step1GetRemoteGroupMembers.ps1 -ComputerName (Get-Content c:\Scripts\DesktopComputers.txt)
 
 .Example - option 3
  Ref48Step1GetRemoteGroupMembers.ps1 -ComputerName Desktop01, Desktop02
#>
#Set-ExecutionPolicy remotesigned -Force
#requires -Modules ActiveDirectory
#requires -version 4.0
#requires -RunAsAdministrator
function Ref48Step1GetRemoteGroupMembers {
[CmdletBinding()]

Param(
 [Parameter( ValueFromPipeline=$true,
 ValueFromPipelineByPropertyName=$true
 )]
 [string[]] $ComputerName,
  [string] $RemoteGroupName = 'Administrators',
  [string] $OutputDir = "c:\Scripts"
)
 
Begin {
 if(!($Computername)) {
  Get-Content c:\scripts\destopComputers.csv
  }
 
 else {
 $Computername = $env:COMPUTERNAME
 }
 
 $OutputFile = Join-Path $OutputDir "RemoteGroupMembers.csv"
 Write-Verbose "Script will write the output to $OutputFile folder"
 Add-Content -Path $OutPutFile -Value "ComputerName, RemoteGroupName, Status, MemberType, MemberDomain, MemberName"
}
 
Process {
 ForEach($Computer in $ComputerName) {
     Write-host "Working on $Computer"
     If(!(Test-Connection -ComputerName $Computer -Count 1 -Quiet)) {
     Write-Verbose "$Computer is offline. Proceeding with next computer"
     Add-Content -Path $OutputFile -Value "$Computer,$RemoteGroupName,Offline"
     Continue
     } else 
        {
         Write-Verbose "Working on $computer"
         try {
             $group = [ADSI]"WinNT://$Computer/$RemoteGroupName"
             $members = @($group.Invoke("Members"))
             Write-Verbose "Successfully queries the members of $computer"
             if(!$members) {
                 Add-Content -Path $OutputFile -Value "$Computer,$RemoteGroupName,NoMembersFound"
                 Write-Verbose "No members found in the group"
                 continue
                 }
            }
         catch {
             Write-Verbose "Failed to query the members of $computer"
             Add-Content -Path $OutputFile -Value "$Computer,,FailedToQuery"
             Continue
             }
         foreach($member in $members) {
         try {
             $MemberName = $member.GetType().Invokemember("Name","GetProperty",$null,$member,$null)
             $MemberType = $member.GetType().Invokemember("Class","GetProperty",$null,$member,$null)
             $MemberPath = $member.GetType().Invokemember("ADSPath","GetProperty",$null,$member,$null)
             $MemberDomain = $null
             if($MemberPath -match "^Winnt\:\/\/(?<domainName>\S+)\/(?<CompName>\S+)\/") {
             if($MemberType -eq "User") {
             $MemberType = "RemoteUser"
             } elseif($MemberType -eq "Group"){
             $MemberType = "RemoteGroup"
             }
             $MemberDomain = $matches["CompName"]
 
             } elseif($MemberPath -match "^WinNT\:\/\/(?<domainname>\S+)/") {
             if($MemberType -eq "User") {
                $MemberType = "DomainUser"
                } 
                elseif($MemberType -eq "Group"){
                    $MemberType = "DomainGroup"
                    }
             $MemberDomain = $matches["domainname"]
 
             } 
             else {
                 $MemberType = "Unknown"
                 $MemberDomain = "Unknown"
                 }
            Add-Content -Path $OutPutFile -Value "$Computer, $RemoteGroupName, SUCCESS, $MemberType, $MemberDomain, $MemberName"
             }
          catch {
            Write-Verbose "failed to query details of a member. Details $_"
            Add-Content -Path $OutputFile -Value "$Computer,,FailedQueryMember"
            }
          }
         }
      }
     }
End {} 
}

Open in new window

0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Windows Server 2003 introduced persistent Volume Shadow Copies and made 2003 a must-do upgrade.  Since then, it's been a must-implement feature for all servers doing any kind of file sharing.
This article is about my experience upgrading my consulting machine to Windows 10 Version 1709 (The Fall 2017 Creator Update)
The viewer will learn how to successfully create a multiboot device using the SARDU utility on Windows 7. Start the SARDU utility: Change the image directory to wherever you store your ISOs, this will prevent you from having 2 copies of an ISO wit…
The Task Scheduler is a powerful tool that is built into Windows. It allows you to schedule tasks (actions) on a recurring basis, such as hourly, daily, weekly, monthly, at log on, at startup, on idle, etc. This video Micro Tutorial is a brief intro…

612 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question