Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Bagian ini menjelaskan cara membuat cmdlet yang mengakses data tersimpan melalui penyedia Windows PowerShell. Jenis cmdlet ini menggunakan infrastruktur penyedia Windows PowerShell dari runtime Windows PowerShell dan, oleh karena itu, kelas cmdlet harus berasal dari kelas dasar System.Management.Automation.PSCmdlet.
Cmdlet Select-Str yang dijelaskan di sini dapat menemukan dan memilih string dalam file atau objek. Pola yang digunakan untuk mengidentifikasi string dapat ditentukan secara eksplisit melalui parameter Path cmdlet atau secara implisit melalui parameter Script.
Cmdlet dirancang untuk menggunakan penyedia Windows PowerShell apa pun yang berasal dari System.Management.Automation.Provider.IContentCmdletProvider. Misalnya, cmdlet dapat menentukan penyedia FileSystem atau Penyedia variabel yang disediakan oleh Windows PowerShell. Untuk informasi selengkapnya tentang penyedia PowerShellWindows, lihat Merancang penyedia Windows PowerShell Anda.
Menentukan Kelas Cmdlet
Langkah pertama dalam pembuatan cmdlet adalah selalu menamai cmdlet dan mendeklarasikan kelas .NET yang mengimplementasikan cmdlet. Cmdlet ini mendeteksi string tertentu, sehingga nama kata kerja yang dipilih di sini adalah "Pilih", yang ditentukan oleh kelas System.Management.Automation.VerbsCommon. Nama kata benda "Str" digunakan karena cmdlet bertindak berdasarkan string. Dalam deklarasi di bawah ini, perhatikan bahwa kata kerja cmdlet dan nama kata benda tercermin dalam nama kelas cmdlet. Untuk informasi selengkapnya tentang kata kerja cmdlet yang disetujui, lihat Nama Kata Kerja Cmdlet.
Kelas .NET untuk cmdlet ini harus berasal dari kelas dasar System.Management.Automation.PSCmdlet, karena menyediakan dukungan yang diperlukan oleh runtime Windows PowerShell untuk mengekspos infrastruktur penyedia Windows PowerShell. Perhatikan bahwa cmdlet ini juga menggunakan kelas ekspresi reguler .NET Framework, seperti System.Text.RegularExpressions.Regex.
Kode berikut adalah definisi kelas untuk cmdlet Select-Str ini.
[Cmdlet(VerbsCommon.Select, "Str", DefaultParameterSetName="PatternParameterSet")]
public class SelectStringCommand : PSCmdlet
Cmdlet ini menentukan parameter default yang ditetapkan dengan menambahkan kata kunci atribut DefaultParameterSetName ke deklarasi kelas. Parameter default yang ditetapkan PatternParameterSet digunakan ketika parameter Script tidak ditentukan. Untuk informasi selengkapnya tentang set parameter ini, lihat diskusi parameter Pattern dan Script di bagian berikut.
Menentukan Parameter untuk Akses Data
Cmdlet ini menentukan beberapa parameter yang memungkinkan pengguna mengakses dan memeriksa data yang disimpan. Parameter ini mencakup parameter Path yang menunjukkan lokasi penyimpanan data, parameter Pattern yang menentukan pola yang akan digunakan dalam pencarian, dan beberapa parameter lain yang mendukung bagaimana pencarian dilakukan.
Nota
Untuk informasi selengkapnya tentang dasar-dasar menentukan parameter, lihat [Menambahkan Parameter yang Memproses Input Baris Perintah][04].
Mendeklarasikan Parameter Jalur
Untuk menemukan penyimpanan data, cmdlet ini harus menggunakan jalur Windows PowerShell untuk mengidentifikasi penyedia Windows PowerShell yang dirancang untuk mengakses penyimpanan data. Oleh karena itu, ini mendefinisikan parameter Path array string jenis untuk menunjukkan lokasi penyedia.
[Parameter(
Position = 0,
ParameterSetName = "ScriptParameterSet",
Mandatory = true)]
[Parameter(
Position = 0,
ParameterSetName = "PatternParameterSet",
ValueFromPipeline = true,
Mandatory = true)]
[Alias("PSPath")]
public string[] Path
{
get { return paths; }
set { paths = value; }
}
private string[] paths;
Perhatikan bahwa parameter ini milik dua set parameter yang berbeda dan memiliki alias.
Dua atribut System.Management.Automation.ParameterAttribute menyatakan bahwa parameter Path milik ScriptParameterSet dan PatternParameterSet. Untuk informasi selengkapnya tentang set parameter, lihat Menambahkan Set Parameter ke Cmdlet.
Atribut System.Management.Automation.AliasAttribute mendeklarasikan alias PSPath untuk parameter Path. Mendeklarasikan alias ini sangat disarankan untuk konsistensi dengan cmdlet lain yang mengakses penyedia Windows PowerShell. Untuk informasi selengkapnya tentang jalur PowerShellWindows, lihat "Konsep Jalur PowerShell" di Cara Kerja Windows PowerShell.
Mendeklarasikan Parameter Pola
Untuk menentukan pola yang akan dicari, cmdlet ini mendeklarasikan parameter Pattern yang merupakan array string. Hasil positif dikembalikan ketika salah satu pola ditemukan di penyimpanan data. Perhatikan bahwa pola ini dapat dikompilasi ke dalam array ekspresi reguler yang dikompilasi atau array pola kartubebas yang digunakan untuk pencarian harfiah.
[Parameter(
Position = 1,
ParameterSetName = "PatternParameterSet",
Mandatory = true)]
public string[] Pattern
{
get { return patterns; }
set { patterns = value; }
}
private string[] patterns;
private Regex[] regexPattern;
private WildcardPattern[] wildcardPattern;
Ketika parameter ini ditentukan, cmdlet menggunakan set parameter default PatternParameterSet.
Dalam hal ini, cmdlet menggunakan pola yang ditentukan di sini untuk memilih string. Sebaliknya, parameter Script juga dapat digunakan untuk menyediakan skrip yang berisi pola. Parameter Script dan Pattern menentukan dua set parameter terpisah, sehingga keduanya saling eksklusif.
Mendeklarasikan Parameter Dukungan Pencarian
Cmdlet ini mendefinisikan parameter dukungan berikut yang dapat digunakan untuk memodifikasi kemampuan pencarian cmdlet.
Parameter Script menentukan blok skrip yang dapat digunakan untuk menyediakan mekanisme pencarian alternatif untuk cmdlet. Skrip harus berisi pola yang digunakan untuk mencocokkan dan mengembalikan objek System.Management.Automation.PSObject. Perhatikan bahwa parameter ini juga merupakan parameter unik yang mengidentifikasi kumpulan parameter ScriptParameterSet. Saat runtime Windows PowerShell melihat parameter ini, runtime hanya menggunakan parameter yang termasuk dalam kumpulan parameter ScriptParameterSet.
[Parameter(
Position = 1,
ParameterSetName = "ScriptParameterSet",
Mandatory = true)]
public ScriptBlock Script
{
set { script = value; }
get { return script; }
}
ScriptBlock script;
Parameter SimpleMatch adalah parameter sakelar yang menunjukkan apakah cmdlet secara eksplisit cocok dengan pola saat disediakan. Ketika pengguna menentukan parameter di baris perintah (true), cmdlet menggunakan pola saat disediakan. Jika parameter tidak ditentukan (false), cmdlet menggunakan ekspresi reguler. Default untuk parameter ini adalah false.
[Parameter]
public SwitchParameter SimpleMatch
{
get { return simpleMatch; }
set { simpleMatch = value; }
}
private bool simpleMatch;
Parameter CaseSensitive adalah parameter sakelar yang menunjukkan apakah pencarian peka huruf besar/kecil dilakukan. Ketika pengguna menentukan parameter di baris perintah (true), cmdlet memeriksa huruf besar dan kecil karakter saat membandingkan pola. Jika parameter tidak ditentukan (false), cmdlet tidak membedakan antara huruf besar dan huruf kecil. Misalnya "MyFile" dan "myfile" keduanya akan dikembalikan sebagai hits positif. Default untuk parameter ini adalah false.
[Parameter]
public SwitchParameter CaseSensitive
{
get { return caseSensitive; }
set { caseSensitive = value; }
}
private bool caseSensitive;
Parameter Exclude dan Include mengidentifikasi item yang secara eksplisit dikecualikan dari atau disertakan dalam pencarian. Secara default, cmdlet akan mencari semua item di penyimpanan data. Namun, untuk membatasi pencarian yang dilakukan oleh cmdlet, parameter ini dapat digunakan untuk secara eksplisit menunjukkan item yang akan disertakan dalam pencarian atau dihilangkan.
[Parameter]
public SwitchParameter CaseSensitive
{
get { return caseSensitive; }
set { caseSensitive = value; }
}
private bool caseSensitive;
[Parameter]
[ValidateNotNullOrEmpty]
public string[] Include
{
get
{
return includeStrings;
}
set
{
includeStrings = value;
this.include = new WildcardPattern[includeStrings.Length];
for (int i = 0; i < includeStrings.Length; i++)
{
this.include[i] = new WildcardPattern(includeStrings[i], WildcardOptions.IgnoreCase);
}
}
}
internal string[] includeStrings = null;
internal WildcardPattern[] include = null;
Mendeklarasikan Set Parameter
Cmdlet ini menggunakan dua set parameter (ScriptParameterSet dan PatternParameterSet, yang merupakan default) sebagai nama dua set parameter yang digunakan dalam akses data.
PatternParameterSet adalah set parameter default dan digunakan saat parameter Pattern ditentukan.
ScriptParameterSet digunakan saat pengguna menentukan mekanisme pencarian alternatif melalui parameter Script. Untuk informasi selengkapnya tentang set parameter, lihat Menambahkan Set Parameter ke Cmdlet.
Mengesampingkan Metode Pemrosesan Input
Cmdlet harus mengambil alih satu atau beberapa metode pemrosesan input untuk kelas System.Management.Automation.PSCmdlet. Untuk informasi selengkapnya tentang metode pemrosesan input, lihat Membuat Cmdlet Pertama Anda.
Cmdlet ini mengambil alih metode System.Management.Automation.Cmdlet.BeginProcessing untuk membangun array ekspresi reguler yang dikompilasi saat startup. Ini meningkatkan performa selama pencarian yang tidak menggunakan pencocokan sederhana.
protected override void BeginProcessing()
{
WriteDebug("Validating patterns.");
if (patterns != null)
{
foreach(string pattern in patterns)
{
if (pattern == null)
ThrowTerminatingError(new ErrorRecord(
new ArgumentNullException(
"Search pattern cannot be null."),
"NullSearchPattern",
ErrorCategory.InvalidArgument,
pattern)
);
}
WriteVerbose("Search pattern(s) are valid.");
// If a simple match is not specified, then
// compile the regular expressions once.
if (!simpleMatch)
{
WriteDebug("Compiling search regular expressions.");
RegexOptions regexOptions = RegexOptions.Compiled;
if (!caseSensitive)
regexOptions |= RegexOptions.Compiled;
regexPattern = new Regex[patterns.Length];
for (int i = 0; i < patterns.Length; i++)
{
try
{
regexPattern[i] = new Regex(patterns[i], regexOptions);
}
catch (ArgumentException ex)
{
ThrowTerminatingError(new ErrorRecord(
ex,
"InvalidRegularExpression",
ErrorCategory.InvalidArgument,
patterns[i]
));
}
} //Loop through patterns to create RegEx objects.
WriteVerbose("Pattern(s) compiled into regular expressions.");
}// If not a simple match.
// If a simple match is specified, then compile the
// wildcard patterns once.
else
{
WriteDebug("Compiling search wildcards.");
WildcardOptions wildcardOptions = WildcardOptions.Compiled;
if (!caseSensitive)
{
wildcardOptions |= WildcardOptions.IgnoreCase;
}
wildcardPattern = new WildcardPattern[patterns.Length];
for (int i = 0; i < patterns.Length; i++)
{
wildcardPattern[i] =
new WildcardPattern(patterns[i], wildcardOptions);
}
WriteVerbose("Pattern(s) compiled into wildcard expressions.");
}// If match is a simple match.
}// If valid patterns are available.
}// End of function BeginProcessing().
Cmdlet ini juga mengambil alih metode System.Management.Automation.Cmdlet.ProcessRecord untuk memproses pilihan string yang dibuat pengguna pada baris perintah. Ini menulis hasil pemilihan string dalam bentuk objek kustom dengan memanggil metode matchString privat.
protected override void ProcessRecord()
{
UInt64 lineNumber = 0;
MatchInfo result;
ArrayList nonMatches = new ArrayList();
// Walk the list of paths and search the contents for
// any of the specified patterns.
foreach (string psPath in paths)
{
// Once the filepaths are expanded, we may have more than one
// path, so process all referenced paths.
foreach(PathInfo path in
SessionState.Path.GetResolvedPSPathFromPSPath(psPath)
)
{
WriteVerbose("Processing path " + path.Path);
// Check if the path represents one of the items to be
// excluded. If so, continue to next path.
if (!MeetsIncludeExcludeCriteria(path.ProviderPath))
continue;
// Get the content reader for the item(s) at the
// specified path.
Collection<IContentReader> readerCollection = null;
try
{
readerCollection =
this.InvokeProvider.Content.GetReader(path.Path);
}
catch (PSNotSupportedException ex)
{
WriteError(new ErrorRecord(ex,
"ContentAccessNotSupported",
ErrorCategory.NotImplemented,
path.Path)
);
return;
}
foreach(IContentReader reader in readerCollection)
{
// Reset the line number for this path.
lineNumber = 0;
// Read in a single block (line in case of a file)
// from the object.
IList items = reader.Read(1);
// Read and process one block(line) at a time until
// no more blocks(lines) exist.
while (items != null && items.Count == 1)
{
// Increment the line number each time a line is
// processed.
lineNumber++;
String message = String.Format("Testing line {0} : {1}",
lineNumber, items[0]);
WriteDebug(message);
result = SelectString(items[0]);
if (result != null)
{
result.Path = path.Path;
result.LineNumber = lineNumber;
WriteObject(result);
}
else
{
// Add the block(line) that did not match to the
// collection of non matches , which will be stored
// in the SessionState variable $NonMatches
nonMatches.Add(items[0]);
}
// Get the next line from the object.
items = reader.Read(1);
}// While loop for reading one line at a time.
}// Foreach loop for reader collection.
}// Foreach loop for processing referenced paths.
}// Foreach loop for walking of path list.
// Store the list of non-matches in the
// session state variable $NonMatches.
try
{
this.SessionState.PSVariable.Set("NonMatches", nonMatches);
}
catch (SessionStateUnauthorizedAccessException ex)
{
WriteError(new ErrorRecord(ex,
"CannotWriteVariableNonMatches",
ErrorCategory.InvalidOperation,
nonMatches)
);
}
}// End of protected override void ProcessRecord().
Mengakses Konten
Cmdlet Anda harus membuka penyedia yang ditunjukkan oleh jalur Windows PowerShell sehingga dapat mengakses data. Objek System.Management.Automation.SessionState untuk runspace digunakan untuk akses ke penyedia, sementara properti System.Management.Automation.PSCmdlet.InvokeProvider* cmdlet digunakan untuk membuka penyedia. Akses ke konten disediakan oleh pengambilan objek System.Management.Automation.ProviderIntrinsics untuk penyedia yang dibuka.
Cmdlet Select-Str sampel ini menggunakan properti System.Management.Automation.ProviderIntrinsics.Content* untuk mengekspos konten yang akan dipindai. Kemudian dapat memanggil metode System.Management.Automation.ContentCmdletProviderIntrinsics.GetReader*, melewati jalur Windows PowerShell yang diperlukan.
Sampel Kode
Kode berikut menunjukkan implementasi versi cmdlet Select-Str ini. Perhatikan bahwa kode ini mencakup kelas cmdlet, metode privat yang digunakan oleh cmdlet, dan kode snap-in Windows PowerShell yang digunakan untuk mendaftarkan cmdlet. Untuk informasi selengkapnya tentang mendaftarkan cmdlet, lihat Membangun Cmdlet.
//
// Copyright (c) 2006 Microsoft Corporation. All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
using System;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Provider;
using System.ComponentModel;
namespace Microsoft.Samples.PowerShell.Commands
{
#region SelectStringCommand
/// <summary>
/// This cmdlet searches through PSObjects for particular patterns.
/// </summary>
/// <remarks>
/// This cmdlet can be used to search any object, such as a file or a
/// variable, whose provider exposes methods for reading and writing
/// content.
/// </remarks>
[Cmdlet(VerbsCommon.Select, "Str", DefaultParameterSetName="PatternParameterSet")]
public class SelectStringCommand : PSCmdlet
{
#region Parameters
/// <summary>
/// Declare a Path parameter that specifies where the data is stored.
/// This parameter must specify a PowerShell that indicates the
/// PowerShell provider that is used to access the objects to be
/// searched for matching patterns. This parameter should also have
/// a PSPath alias to provide consistency with other cmdlets that use
/// PowerShell providers.
/// </summary>
/// <value>Path of the object(s) to search.</value>
[Parameter(
Position = 0,
ParameterSetName = "ScriptParameterSet",
Mandatory = true)]
[Parameter(
Position = 0,
ParameterSetName = "PatternParameterSet",
ValueFromPipeline = true,
Mandatory = true)]
[Alias("PSPath")]
public string[] Path
{
get { return paths; }
set { paths = value; }
}
private string[] paths;
/// <summary>
/// Declare a Pattern parameter that specifies the pattern(s)
/// used to find matching patterns in the string representation
/// of the objects. A positive result will be returned
/// if any of the patterns are found in the objects.
/// </summary>
/// <remarks>
/// The patterns will be compiled into an array of wildcard
/// patterns for a simple match (literal string matching),
/// or the patterns will be converted into an array of compiled
/// regular expressions.
/// </remarks>
/// <value>Array of patterns to search.</value>
[Parameter(
Position = 1,
ParameterSetName = "PatternParameterSet",
Mandatory = true)]
public string[] Pattern
{
get { return patterns; }
set { patterns = value; }
}
private string[] patterns;
private Regex[] regexPattern;
private WildcardPattern[] wildcardPattern;
/// <summary>
/// Declare a Script parameter that specifies a script block
/// that is called to perform the matching operations
/// instead of the matching performed by the cmdlet.
/// </summary>
/// <value>Script block that will be called for matching</value>
[Parameter(
Position = 1,
ParameterSetName = "ScriptParameterSet",
Mandatory = true)]
public ScriptBlock Script
{
set { script = value; }
get { return script; }
}
ScriptBlock script;
/// <summary>
/// Declare a switch parameter that specifies if the pattern(s) are used
/// literally. If not (default), searching is
/// done using regular expressions.
/// </summary>
/// <value>If True, a literal pattern is used.</value>
[Parameter]
public SwitchParameter SimpleMatch
{
get { return simpleMatch; }
set { simpleMatch = value; }
}
private bool simpleMatch;
/// <summary>
/// Declare a switch parameter that specifies if a case-sensitive
/// search is performed. If not (default), a case-insensitive search
/// is performed.
/// </summary>
/// <value>If True, a case-sensitive search is made.</value>
[Parameter]
public SwitchParameter CaseSensitive
{
get { return caseSensitive; }
set { caseSensitive = value; }
}
private bool caseSensitive;
/// <summary>
/// Declare an Include parameter that species which
/// specific items are searched. When this parameter
/// is used, items that are not listed here are omitted
/// from the search.
/// </summary>
[Parameter]
[ValidateNotNullOrEmpty]
public string[] Include
{
get
{
return includeStrings;
}
set
{
includeStrings = value;
this.include = new WildcardPattern[includeStrings.Length];
for (int i = 0; i < includeStrings.Length; i++)
{
this.include[i] = new WildcardPattern(includeStrings[i], WildcardOptions.IgnoreCase);
}
}
}
internal string[] includeStrings = null;
internal WildcardPattern[] include = null;
/// <summary>
/// Declare an Exclude parameter that species which
/// specific items are omitted from the search.
/// </summary>
///
[Parameter]
[ValidateNotNullOrEmpty]
public string[] Exclude
{
get
{
return excludeStrings;
}
set
{
excludeStrings = value;
this.exclude = new WildcardPattern[excludeStrings.Length];
for (int i = 0; i < excludeStrings.Length; i++)
{
this.exclude[i] = new WildcardPattern(excludeStrings[i], WildcardOptions.IgnoreCase);
}
}
}
internal string[] excludeStrings;
internal WildcardPattern[] exclude;
#endregion Parameters
#region Overrides
/// <summary>
/// If regular expressions are used for pattern matching,
/// then build an array of compiled regular expressions
/// at startup. This increases performance during scanning
/// operations when simple matching is not used.
/// </summary>
protected override void BeginProcessing()
{
WriteDebug("Validating patterns.");
if (patterns != null)
{
foreach(string pattern in patterns)
{
if (pattern == null)
ThrowTerminatingError(new ErrorRecord(
new ArgumentNullException(
"Search pattern cannot be null."),
"NullSearchPattern",
ErrorCategory.InvalidArgument,
pattern)
);
}
WriteVerbose("Search pattern(s) are valid.");
// If a simple match is not specified, then
// compile the regular expressions once.
if (!simpleMatch)
{
WriteDebug("Compiling search regular expressions.");
RegexOptions regexOptions = RegexOptions.Compiled;
if (!caseSensitive)
regexOptions |= RegexOptions.Compiled;
regexPattern = new Regex[patterns.Length];
for (int i = 0; i < patterns.Length; i++)
{
try
{
regexPattern[i] = new Regex(patterns[i], regexOptions);
}
catch (ArgumentException ex)
{
ThrowTerminatingError(new ErrorRecord(
ex,
"InvalidRegularExpression",
ErrorCategory.InvalidArgument,
patterns[i]
));
}
} //Loop through patterns to create RegEx objects.
WriteVerbose("Pattern(s) compiled into regular expressions.");
}// If not a simple match.
// If a simple match is specified, then compile the
// wildcard patterns once.
else
{
WriteDebug("Compiling search wildcards.");
WildcardOptions wildcardOptions = WildcardOptions.Compiled;
if (!caseSensitive)
{
wildcardOptions |= WildcardOptions.IgnoreCase;
}
wildcardPattern = new WildcardPattern[patterns.Length];
for (int i = 0; i < patterns.Length; i++)
{
wildcardPattern[i] =
new WildcardPattern(patterns[i], wildcardOptions);
}
WriteVerbose("Pattern(s) compiled into wildcard expressions.");
}// If match is a simple match.
}// If valid patterns are available.
}// End of function BeginProcessing().
/// <summary>
/// Process the input and search for the specified patterns.
/// </summary>
protected override void ProcessRecord()
{
UInt64 lineNumber = 0;
MatchInfo result;
ArrayList nonMatches = new ArrayList();
// Walk the list of paths and search the contents for
// any of the specified patterns.
foreach (string psPath in paths)
{
// Once the filepaths are expanded, we may have more than one
// path, so process all referenced paths.
foreach(PathInfo path in
SessionState.Path.GetResolvedPSPathFromPSPath(psPath)
)
{
WriteVerbose("Processing path " + path.Path);
// Check if the path represents one of the items to be
// excluded. If so, continue to next path.
if (!MeetsIncludeExcludeCriteria(path.ProviderPath))
continue;
// Get the content reader for the item(s) at the
// specified path.
Collection<IContentReader> readerCollection = null;
try
{
readerCollection =
this.InvokeProvider.Content.GetReader(path.Path);
}
catch (PSNotSupportedException ex)
{
WriteError(new ErrorRecord(ex,
"ContentAccessNotSupported",
ErrorCategory.NotImplemented,
path.Path)
);
return;
}
foreach(IContentReader reader in readerCollection)
{
// Reset the line number for this path.
lineNumber = 0;
// Read in a single block (line in case of a file)
// from the object.
IList items = reader.Read(1);
// Read and process one block(line) at a time until
// no more blocks(lines) exist.
while (items != null && items.Count == 1)
{
// Increment the line number each time a line is
// processed.
lineNumber++;
String message = String.Format("Testing line {0} : {1}",
lineNumber, items[0]);
WriteDebug(message);
result = SelectString(items[0]);
if (result != null)
{
result.Path = path.Path;
result.LineNumber = lineNumber;
WriteObject(result);
}
else
{
// Add the block(line) that did not match to the
// collection of non matches , which will be stored
// in the SessionState variable $NonMatches
nonMatches.Add(items[0]);
}
// Get the next line from the object.
items = reader.Read(1);
}// While loop for reading one line at a time.
}// Foreach loop for reader collection.
}// Foreach loop for processing referenced paths.
}// Foreach loop for walking of path list.
// Store the list of non-matches in the
// session state variable $NonMatches.
try
{
this.SessionState.PSVariable.Set("NonMatches", nonMatches);
}
catch (SessionStateUnauthorizedAccessException ex)
{
WriteError(new ErrorRecord(ex,
"CannotWriteVariableNonMatches",
ErrorCategory.InvalidOperation,
nonMatches)
);
}
}// End of protected override void ProcessRecord().
#endregion Overrides
#region PrivateMethods
/// <summary>
/// Check for a match using the input string and the pattern(s)
/// specified.
/// </summary>
/// <param name="input">The string to test.</param>
/// <returns>MatchInfo object containing information about
/// result of a match</returns>
private MatchInfo SelectString(object input)
{
string line = null;
try
{
// Convert the object to a string type
// safely using language support methods
line = (string)LanguagePrimitives.ConvertTo(
input,
typeof(string)
);
line = line.Trim(' ','\t');
}
catch (PSInvalidCastException ex)
{
WriteError(new ErrorRecord(
ex,
"CannotCastObjectToString",
ErrorCategory.InvalidOperation,
input)
);
return null;
}
MatchInfo result = null;
// If a scriptblock has been specified, call it
// with the path for processing. It will return
// one object.
if (script != null)
{
WriteDebug("Executing script block.");
Collection<PSObject> psObjects =
script.Invoke(
line,
simpleMatch,
caseSensitive
);
foreach (PSObject psObject in psObjects)
{
if (LanguagePrimitives.IsTrue(psObject))
{
result = new MatchInfo();
result.Line = line;
result.IgnoreCase = !caseSensitive;
break;
} //End of If.
} //End ForEach loop.
} // End of If if script exists.
// If script block exists, see if this line matches any
// of the match patterns.
else
{
int patternIndex = 0;
while (patternIndex < patterns.Length)
{
if ((simpleMatch &&
wildcardPattern[patternIndex].IsMatch(line))
|| (regexPattern != null
&& regexPattern[patternIndex].IsMatch(line))
)
{
result = new MatchInfo();
result.IgnoreCase = !caseSensitive;
result.Line = line;
result.Pattern = patterns[patternIndex];
break;
}
patternIndex++;
}// While loop through patterns.
}// Else for no script block specified.
return result;
}// End of SelectString
/// <summary>
/// Check whether the supplied name meets the include/exclude criteria.
/// That is - it's on the include list if the include list was
/// specified, and not on the exclude list if the exclude list was specified.
/// </summary>
/// <param name="path">path to validate</param>
/// <returns>True if the path is acceptable.</returns>
private bool MeetsIncludeExcludeCriteria(string path)
{
bool ok = false;
// See if the file is on the include list.
if (this.include != null)
{
foreach (WildcardPattern patternItem in this.include)
{
if (patternItem.IsMatch(path))
{
ok = true;
break;
}
}
}
else
{
ok = true;
}
if (!ok)
return false;
// See if the file is on the exclude list.
if (this.exclude != null)
{
foreach (WildcardPattern patternItem in this.exclude)
{
if (patternItem.IsMatch(path))
{
ok = false;
break;
}
}
}
return ok;
} //MeetsIncludeExcludeCriteria
#endregion Private Methods
}// class SelectStringCommand
#endregion SelectStringCommand
#region MatchInfo
/// <summary>
/// Class representing the result of a pattern/literal match
/// that is passed through the pipeline by the Select-Str cmdlet.
/// </summary>
public class MatchInfo
{
/// <summary>
/// Indicates if the match was done ignoring case.
/// </summary>
/// <value>True if case was ignored.</value>
public bool IgnoreCase
{
get { return ignoreCase; }
set { ignoreCase = value; }
}
private bool ignoreCase;
/// <summary>
/// Specifies the number of the matching line.
/// </summary>
/// <value>The number of the matching line.</value>
public UInt64 LineNumber
{
get { return lineNumber; }
set { lineNumber = value; }
}
private UInt64 lineNumber;
/// <summary>
/// Specifies the text of the matching line.
/// </summary>
/// <value>The text of the matching line.</value>
public string Line
{
get { return line; }
set { line = value; }
}
private string line;
/// <summary>
/// Specifies the full path of the object(file) containing the
/// matching line.
/// </summary>
/// <remarks>
/// It will be "inputStream" if the object came from the input
/// stream.
/// </remarks>
/// <value>The path name</value>
public string Path
{
get { return path; }
set
{
pathSet = true;
path = value;
}
}
private string path;
private bool pathSet;
/// <summary>
/// Specifies the pattern that was used in the match.
/// </summary>
/// <value>The pattern string</value>
public string Pattern
{
get { return pattern; }
set { pattern = value; }
}
private string pattern;
private const string MatchFormat = "{0}:{1}:{2}";
/// <summary>
/// Returns the string representation of this object. The format
/// depends on whether a path has been set for this object or
/// not.
/// </summary>
/// <remarks>
/// If the path component is set, as would be the case when
/// matching in a file, ToString() returns the path, line
/// number and line text. If path is not set, then just the
/// line text is presented.
/// </remarks>
/// <returns>The string representation of the match object.</returns>
public override string ToString()
{
if (pathSet)
return String.Format(
System.Threading.Thread.CurrentThread.CurrentCulture,
MatchFormat,
this.path,
this.lineNumber,
this.line
);
else
return this.line;
}
}// End class MatchInfo
#endregion
#region PowerShell snap-in
/// <summary>
/// Create a PowerShell snap-in for the Select-Str cmdlet.
/// </summary>
[RunInstaller(true)]
public class SelectStringPSSnapIn : PSSnapIn
{
/// <summary>
/// Create an instance of the SelectStrPSSnapin class.
/// </summary>
public SelectStringPSSnapIn()
: base()
{
}
/// <summary>
/// Specify the name of the PowerShell snap-in.
/// </summary>
public override string Name
{
get
{
return "SelectStrPSSnapIn";
}
}
/// <summary>
/// Specify the vendor of the PowerShell snap-in.
/// </summary>
public override string Vendor
{
get
{
return "Microsoft";
}
}
/// <summary>
/// Specify the localization resource information for the vendor.
/// Use the format: SnapinName,VendorName.
/// </summary>
public override string VendorResource
{
get
{
return "SelectStrSnapIn,Microsoft";
}
}
/// <summary>
/// Specify the description of the PowerShell snap-in.
/// </summary>
public override string Description
{
get
{
return "This is a PowerShell snap-in for the Select-Str cmdlet.";
}
}
/// <summary>
/// Specify the localization resource information for the description.
/// Use the format: SnapinName,Description.
/// </summary>
public override string DescriptionResource
{
get
{
return "SelectStrSnapIn,This is a PowerShell snap-in for the Select-Str cmdlet.";
}
}
}
#endregion PowerShell snap-in
} //namespace Microsoft.Samples.PowerShell.Commands;
Membangun Cmdlet
Setelah menerapkan cmdlet, Anda harus mendaftarkannya dengan Windows PowerShell melalui snap-in Windows PowerShell. Untuk informasi selengkapnya tentang mendaftarkan cmdlet, lihat Cara Mendaftarkan Cmdlet, Penyedia, dan Aplikasi Host.
Menguji Cmdlet
Ketika cmdlet Anda telah terdaftar di Windows PowerShell, Anda dapat mengujinya dengan menjalankannya di baris perintah. Prosedur berikut dapat digunakan untuk menguji sampel Select-Str cmdlet.
Mulai Windows PowerShell, dan cari file Catatan untuk kemunculan baris dengan ekspresi ".NET". Perhatikan bahwa tanda kutip di sekitar nama jalur hanya diperlukan jika jalur terdiri dari lebih dari satu kata.
Select-Str -Path "notes" -Pattern ".NET" -SimpleMatch=$falseOutput berikut muncul.
IgnoreCase : True LineNumber : 8 Line : Because Windows PowerShell works directly with .NET objects, there is often a .NET object Path : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes Pattern : .NET IgnoreCase : True LineNumber : 21 Line : You should normally define the class for a cmdlet in a .NET namespace Path : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes Pattern : .NETCari file Catatan untuk kemunculan baris dengan kata "over", diikuti oleh teks lainnya. Parameter
SimpleMatchmenggunakan nilai defaultfalse. Pencarian tidak peka huruf besar/kecil karena parameterCaseSensitivediatur kefalse.Select-Str -Path notes -Pattern "over*" -SimpleMatch -CaseSensitive:$falseOutput berikut muncul.
IgnoreCase : True LineNumber : 45 Line : Override StopProcessing Path : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes Pattern : over* IgnoreCase : True LineNumber : 49 Line : overriding the StopProcessing method Path : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes Pattern : over*Cari file Catatan menggunakan ekspresi reguler sebagai pola. Cmdlet mencari karakter alfabet dan spasi kosong yang diapit dalam tanda kurung.
Select-Str -Path notes -Pattern "\([A-Za-z:blank:]" -SimpleMatch:$falseOutput berikut muncul.
IgnoreCase : True LineNumber : 1 Line : Advisory Guidelines (Consider Following) Path : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes Pattern : \([A-Za-z:blank:] IgnoreCase : True LineNumber : 53 Line : If your cmdlet has objects that are not disposed of (written to the pipeline) Path : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes Pattern : \([A-Za-z:blank:]Lakukan pencarian peka huruf besar/kecil dari file Catatan untuk kemunculan kata "Parameter".
Select-Str -Path notes -Pattern Parameter -CaseSensitiveOutput berikut muncul.
IgnoreCase : False LineNumber : 6 Line : Support an InputObject Parameter Path : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes Pattern : Parameter IgnoreCase : False LineNumber : 30 Line : Support Force Parameter Path : C:\PowerShell-Progs\workspace\Samples\SelectStr\notes Pattern : ParameterCari penyedia Variabel yang dikirim dengan Windows PowerShell untuk variabel yang memiliki nilai numerik dari 0 hingga 9.
Select-Str -Path * -Pattern "[0-9]"Output berikut muncul.
IgnoreCase : True LineNumber : 1 Line : 64 Path : Variable:\MaximumHistoryCount Pattern : [0-9]Gunakan blok skrip untuk mencari file SelectStrCommandSample.cs string "Pos". Operator
-cmatchmelakukan kecocokan pola yang tidak peka huruf besar/kecil.Select-Str -Path "SelectStrCommandSample.cs" -Script { if ($args[0] -cmatch "Pos"){ return $true } return $false }Output berikut muncul.
IgnoreCase : True LineNumber : 37 Line : Position = 0. Path : C:\PowerShell-Progs\workspace\Samples\SelectStr\SelectStrCommandSample.cs Pattern :
Lihat Juga
Cara Membuat Cmdlet Windows PowerShell
Membuat Cmdlet Pertama Anda
Membuat Cmdlet yang Memodifikasi Sistem
Merancang Penyedia Windows PowerShell Anda