2010-05-28 17 views
6

Arrrg! Me encuentro con lo que siento es un problema tonto con un simple script que estoy escribiendo en powershell. Invoco un comando sql que llama a un proceso almacenado, con los resultados lo pongo en una matriz. Los resultados se ven algo como esto:¿Por qué no puedo llamar al método Contiene desde mi matriz?

Status          ProcessStartTime       ProcessEndTime        
------          ----------------       --------------        
Expired          May 22 2010 8:31PM       May 22 2010 8:32PM 

Lo que estoy tratando de hacer es if($s.Contains("Expired")), informe no. Sencillo...? :(Problema al que me estoy enfrentando es que parece que el método Contiene no se está cargando porque me sale un error como este:

La invocación del método falló porque [System.Object []] no contiene un método llamado ' contiene en la línea:. 1 carácter: 12 + $ s.Contains < < < < ("caducado") + CategoryInfo: InvalidOperation: (contiene: String) [], RuntimeException + FullyQualifiedErrorId: methodNotFound

Entonces, ¿qué puedo hacer para evitar que powershell se desenrolle en la secuencia de comandos de la secuencia de comandos de PS a continuación -

$s = @(Invoke-Sqlcmd -Query "USE DB 
     GO 
     exec Monitor_TEST_ps 'EXPORT_RUN',NULL,20" ` 
     -ServerInstance testdb002\testdb_002 
    ) 

if ($s.Contains("Expired")) 
{ 
    Write-Host "Expired found, FAIL." 
} 
else 
{ 
    Write-Host "Not found, OK." 
} 

Respuesta

5

La razón por la que ve el método es Get-Members es que powershell está tratando de ser útil y desenrollar la colección. Si tiene una matriz con varios tipos de elementos, le muestra los miembros para cada tipo (como si 'ls' (Get-ChildItem) y FileInfos y DirectoryInfos están en el directorio en el que se encuentra, y usted canaliza ls | gm , se le mostrará los miembros de FileInfos y también otro grupo de miembros de DirectoryInfos):

(7) C:\ -» ls 


    Directory: C:\ 


Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
d----   5/28/2010 8:19 AM   .hg 
d----   5/13/2010 3:37 PM   Build 
… 
-a---   4/22/2010 11:21 AM  2603 TODO.org 


(8) C:\ -» ls | gm 


    TypeName: System.IO.DirectoryInfo 

Name      MemberType  Definition 
----      ----------  ---------- 
Mode      CodeProperty System.String Mode{get=Mode;} 
Create     Method   System.Void Create(System.Security.AccessControl.Direct... 
… 

    TypeName: System.IO.FileInfo 

Name      MemberType  Definition 
----      ----------  ---------- 
Mode      CodeProperty System.String Mode{get=Mode;} 
AppendText    Method   System.IO.StreamWriter AppendText() 
… 

lo que suelo hacer, para asegurarse de que no estoy mirando a los miembros desenrollados, es tratar de “$ s.GetType() .Name "primero para ver a qué me refiero. En su caso, es claro y ordenado, ya que lo inicializó como "$ s = @ (Invo" (el @ = es una matriz)

Para saber si una matriz contiene un elemento, puede usar - contiene operador:

(9) C:\ -» @(1,2,3) -contains 1 
True 

Creo que tienes una matriz de cadenas, por lo que es posible utilizar una cadena literal, como:

(10) C:\ -» @("Stuff","you've","got","might have","Expired") -contains "Expired" 
True 

Pero si el caducada no es una coincidencia exacta (se buscaba un elemento que haya caducado, como "Conexión caducada 1/1/2010") necesita encontrar coincidencias y verificar th e cuento, pienso:

(23) C:\ -» @("Stuff","you've","got","might have","Connection Expired 1/1/2010") -contains "Expired" 
False 
(24) C:\ -» @("Stuff","you've","got","might have","Connection Expired 1/1/2010") | ?{$_.Contains("Expired")} 
Connection Expired 1/1/2010 
(33) C:\ -» $xs = @("Stuff","you've","got","might have","Connection Expired 1/1/2010") | ?{$_.Contains("Expired")} 
(34) C:\ -» $xs.GetType() 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  String         System.Object 


(35) C:\ -» $xs 
Connection Expired 1/1/2010 

En este caso, no es sólo un partido, así que PowerShell desenrollé en una cadena. Imbécil. Si hay más de 1 coincidencia, sin embargo:

(36) C:\ -» $xs = @("Stuff","you've","got","might Expired have","Connection Expired 1/1/2010") | ?{$_.Contains("Expired")} 
(37) C:\ -» $xs.GetType() 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  Object[]         System.Array 


(38) C:\ -» $xs 
might Expired have 
Connection Expired 1/1/2010 

Ahora es una matriz.

Afortunadamente, tanto la cadena y la matriz tienen una propiedad de longitud:

(39) C:\ -» $xs.Length 
2 
(40) C:\ -» "Bob".Length 
3 

para que pueda comprobar la longitud de sus resultados que contienen “caducado” para ver si hay alguna de expirado:

(41) C:\ -» $xs = @("Stuff","you've","got","might Expired have","Connection Expired 1/1/2010") | ?{$_.Contains("Expired")} 
(42) C:\ -» if ($xs.Length -gt 0) { Write-Host "Whoas, stuff's expired, dog." } 
Whoas, shit's expired, dog. 

(tal vez alguien tiene una mejor manera de comprobar si una colección contiene un elemento que satisface algún predicado (como LINQ's Any)?)

+0

Gracias Chris! Esto definitivamente me llevó en la dirección correcta. guión de trabajo: $ s = @ (Invoke-Sqlcmd -query "USO DB GO exec Monitor_TEST_ps 'EXPORT_RUN', NULL, 20" ' -ServerInstance "testdb002 \ testdb_002") if ($ s | {? $ _ ['Status'] -eq 'OK'}) { Write-Host "Expired found, FAIL." } else { Write-Host "No encontrado, OK". } – xbnevan

7

En pocas palabras, $ s es una matriz .NET (' reutilizar @() asegura que) y está intentando invocar un método (Contiene) que no existe en este tipo .NET.

La forma más sencilla de resolver el problema es utilizar el operador de la PowerShell -contains que tiene las ventajas de trabajar en contra de las matrices directamente y haciendo caso insenstive compara ej .:

if ($s -contains 'expired') { ... } 
+0

Guau, podría haber jurado que me cansé de eso. Me siento tonto ahora, gracias Keith que funcionó bien. w00t. – xbnevan

+1

Simple y al grano. Exactamente lo que necesitaba. Estaba desarrollando un sistema de PS 3 y luego intenté ejecutar mi código en PS 2. Recibí este error y esta es una solución simple para solucionar el problema. –

Cuestiones relacionadas