2015-07-07 13 views
7

Interrogazione di un oggetto WMI sulcosa è questo formato per secondi XXXXXXX.XXXXX: XXX (Win32_NetworkLoginProfile)

$colItems = Get-WmiObject Win32_NetworkLoginProfile -Namespace "root\CIMV2" 
        | Where-Object {$_.name -match "Name"} | Select-Object name,PasswordAge 

secondo MSDN

PasswordAge

tipo

dati: datetime
Tipo di accesso: Sola lettura
Periodo di validità della password. Questo valore è misurato dal numero di secondi trascorsi dall'ultima modifica della password.
Esempio: 00001201000230,000000 000

sto ottenendo

00000068235223.000000:000 

Così ho cercato lanciare questo per TimeSpan e DateTime senza fortuna. che cosa rappresentano i due punti su come ottenere il numero di ore che rappresenta.


Grazie Aggiunta del nome classe WMI al titolo per la prossima povera anima che viene confusa dal testo della documentazione.


qui è quello che funziona

che ha funzionato perfettamente $ str = "00000068235223,000000: 000" $ ts = [System.Management.ManagementDateTimeConverter] :: ToTimeSpan ($ str)

Giorni: 68 Ore: 23 Minuti: 52 secondi: 23 millisecondi 0 Zecche: 59611430000000 TotalDays: 68,9947106481481 totalhours: 1655.87305555556 totalminutes: 99352.3833333333 totalseconds: 5961143 TotalMilliseconds: 5961143000

+0

possibile duplicato di [Come convertire una stringa datetime lungo per giorni in C#] (http://stackoverflow.com/questions/22352308/how-to-convert-a-long- datetime-string-to-days-in-c-sharp) –

+0

Il formato effettivo di 'PasswordAge' è' "ddddddddHHmmss.ffffff: 000" 'cioè 8 cifre di giorni, quindi 2 cifre di ore, quindi minuti, quindi secondi, quindi frazioni. Dicono usa '[TimeSpan] :: ParseExact ($ stringa," ddddddddHHmmss.ffffff: 000 ", $ null)' ma non riesco a farlo funzionare nella mia PS4/Win7. Molto strano. – Vesper

+0

@Vesper: vedi il mio commento qui sotto. – PaulF

risposta

5

Questo è il tempo formato intervallo DTMF documentata here. Fondamentalmente è una stringa che codifica un intervallo di tempo nel formato ddddddddHHMMSS.mmmmmm:000. Si noti che per gli intervalli di tempo, il finale è sempre :000.

Dalla documentazione:

Il seguente esempio illustra il formato di un intervallo di data e ora. ddddddddHHMMSS.mmmmmm: 000
Nella tabella seguente sono elencati i campi dell'intervallo di data e ora.
Campo Descrizione
dddddddd Otto cifre che rappresentano un numero di giorni (da 00000000 a 99999999).
HH Ora a due cifre del giorno che utilizza l'orologio a 24 ore (da 00 a 23).
MM Minuto a due cifre nell'ora (da 00 a 59).
SS Numero a due cifre di secondi nel minuto (da 00 a 59).
mmmmmm Numero a sei cifre di microsecondi nel secondo (da 000000 a 999999).

credo che la documentazione è un po 'fuorviante per questo campo, dal momento che è implicando i numeri interi sono secondi pieni, ma in realtà si tratta di un formato di stringa che rappresenta giorni, ore, minuti, secondi, ecc

Si dovrebbe usare [System.Management.ManagementDateTimeConverter]::ToTimeSpan per convertire questa stringa per un periodo di .NET, tuttavia, per qualsiasi motivo ho effettivamente ricevuto una matrice invece che una stringa per PasswordAge, così ho dovuto usare questo:

$p = gwmi Win32_NetworkLoginProfile 
[System.Management.ManagementDateTimeConverter]::ToTimeSpan($p.PasswordAge[1]) 
+0

Penso che sia solo mal formulato - dicendo che è _misurato dal numero di secondi_ non che sia il numero di secondi. È fuorviante sul formato datetime anziché sull'intervallo di tempo. – PaulF

+0

Il problema principale che '[TimeSpan] :: ParseExact ($ stringa," ddddddddHHmmss.ffffff: 000 ", $ null)' non produce un intervallo di tempo valido con nessuna delle stringhe fornite, mentre i documenti dicono che dovrebbe. – Vesper

+0

@Vesper: vedere http://stackoverflow.com/questions/11719055/why-does-timespan-parseexact-not-work. La stringa di formato corretta dovrebbe essere @ "ddddddddhhmmss \.ffffff \: \ 0 \ 0 \ 0 "(nota hh non HH ed escaping di TUTTI i valori che non sono definiti specificatori per intervallo di tempo) – PaulF

4

per aggiungere a tutto le risposte precedenti, la routine corretta per fare qualcosa di questo tipo di stringhe è chiamata [System.Management.ManagementDateTimeConverter]::ToTimeSpan($string). Ciò produrrà un oggetto [System.TimeSpan], che è quindi possibile analizzare in un modo migliore.

Il credito per la conversione da classe va a this answer.

+0

Avrei menzionato questo nella mia risposta, tuttavia i miei tentativi hanno sempre ricevuto un errore dicendo che il valore . "out of range di valori validi" –

+0

che ha funzionato perfettamente $ str = "00000068235223,000000: 000" $ ts = [System.Management.ManagementDateTimeConverter] :: ToTimeSpan ($ str) $ ts Giorni: 68 Ore: 23 Minuti: 52 secondi: 23 millisecondi 0 Zecche: 59611430000000 TotalDays: 68,9947106481481 TotalHours: 1655.87305555556 TotalMinutes: 99352.3833333333 TotalSeconds: 5961143 TotalMilliseconds: 5961143000 – user1088352

+0

Ok per qualche motivo 'PasswordAge' è un array per me, non so perché, ma funziona. –

1

Questi sono CIM_DATETIME values o Interval values. Il formato è definito dallo standard CIM su cui è basata WMI.

Con i valori di data/ora normali, l'oggetto WMI fornisce una funzione convertitore. Per esempio:

$_.ConvertToDateTime($_.PasswordExpires); 

Ma questo non funziona per gli intervalli, che è quello che è PasswordAge.

Il documento MS si punta dice il valore è il numero di secondi, ma credo che significa la precisione è al secondo, non che il valore è letteralmente in secondi. La mia attuale password dice che ha 43 anni, ad esempio, e questo non è possibile. Quindi deve usare il formato dell'intervallo.

farei questo:

$PasswordAge = New-TimeSpan -Days $_.PasswordAge.Substring(0,8) ` 
    -Hours $_.PasswordAge.Substring(8,2) ` 
    -Minutes $_.PasswordAge.Substring(10,2) ` 
    -Seconds $_.PasswordAge.Substring(12,2); 

ricordatevi di usare $PasswordAge.TotalHours e non solo $PasswordAge.Hours se si desidera che il valore di età effettiva espresso in ore e non solo il valore ora del periodo.

Modifica: @Vesper ha ragione. Si può semplicemente utilizzare:

[System.Management.ManagementDateTimeConverter]::ToTimeSpan($_.PasswordAge); 
Problemi correlati