Solved

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

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

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

The curse of the end user strikes again      

You’ve updated all your end user’s email signatures. Hooray! But guess what? They’re playing around with the HTML, adding stupid taglines and ruining the imagery. Find out how you can save your signatures from end users today.

Question has a verified solution.

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

Suggested Solutions

Our Group Policy work started with Small Business Server in 2000. Microsoft gave us an excellent OU and GPO model in subsequent SBS editions that utilized WMI filters, OU linking, and VBS scripts. These are some of experiences plus our spending a lo…
NTFS file system has been developed by Microsoft that is widely used by Windows NT operating system and its advanced versions. It is the mostly used over FAT file system as it provides superior features like reliability, security, storage, efficienc…
Windows 8 comes with a dramatically different user interface known as Metro. Notably missing from the new interface is a Start button and Start Menu. Many users do not like it, much preferring the interface of earlier versions — Windows 7, Windows X…
With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…

932 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

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now