Solved

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

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

Connect further...control easier

With the ATEN CE624, you can now enjoy a high-quality visual experience powered by HDBaseT technology and the convenience of a single Cat6 cable to transmit uncompressed video with zero latency and multi-streaming for dual-view applications where remote access is required.

Question has a verified solution.

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

When you start your Windows 10 PC and got an "Operating system not found" error or just saw  "Auto repair for startup" or a blinking cursor with black screen. A loop for Auto repair will start but fix nothing.  You will be panic as there are no back…
When you try to extract and to view the contents of a Microsoft Update Standalone Package (MSU) for Windows Vista, you cannot extract the files from the MSU. Here we are going to explain how to extract those hotfix details without using any third pa…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…

735 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