Solved

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

Posted on 2015-02-03
3
395 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 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 80

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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

If you get continual lockouts after changing your Active Directory password, there are several possible reasons.  Two of the most common are using other devices to access your email and stored passwords in the credential manager of windows.
How to record audio from input sources to your PC – connected devices, connected preamp to record vinyl discs, streaming media, that play through your audio card: Vista, Windows 7, Windows 8, Windows 8.1 and Windows 10 – both 32 bit & 64.
Windows 8 came with a dramatically different user interface known as Metro. Notably missing from that interface was a Start button and Start Menu. Microsoft responded to negative user feedback of the Metro interface, bringing back the Start button a…
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…

856 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