Solved

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

Posted on 2015-02-03
3
440 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
3 Comments
 
LVL 40

Accepted Solution

by:
Subsun earned 500 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 82

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

Want Experts Exchange at your fingertips?

With Experts Exchange’s latest app release, you can now experience our most recent features, updates, and the same community interface while on-the-go. Download our latest app release at the Android or Apple stores today!

Question has a verified solution.

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

This article summaries thoughts and ideas from two years of sustained use. It provides good reasoning to make the jump to Windows 10.
An introduction to the wonderful sport of Scam Baiting.  Learn how to help fight scammers by beating them at their own game. This great pass time helps the world, while providing an endless source of entertainment. Enjoy!
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
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…

623 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