@{...=...; ...=...}
é uma hashtable . Você pode conhecê-los como "dicionários" em outros idiomas. Estes são pares chave / valor. Os pontos-e-vírgulas ( ;
) separam os diferentes pares, e a chave e o valor são separados por um sinal de igual ( =
). Note que a chave pode ter citações implícitas, tornando-a uma string.
A parte { "{0:N0}" -f ($_.Length / 1KB) }
é um bloco de script . Há um monte desses; todas as chaves Expression
nas tabelas de hash são mapeadas para uma. Você pode dizer isso pelas chaves sem um prefixo em torno dele. Estas são essencialmente funções anônimas (lambdas). O $_
é o item atual do pipeline, portanto, quando esse bloco de script é executado, ele é expandido para um único item a partir da entrada do pipeline.
O bloco de script em particular "{0:N0}" -f ($_.Length / 1KB)
part está apenas usando o % operador de-f
para fazer a formatação . Isso equivale ao String.Format
do .NET, onde a cadeia padrão está à esquerda e os argumentos para o padrão são uma matriz de objetos à direita. O 0
é apenas o índice do argumento (portanto, primeiro argumento) e o :N0
indica que ele deve ser formatado como um número com 0 casas decimais.
Agora, entre todas as hashtables, temos um monte de vírgulas. Isso cria uma matriz ! Acontece que a parte @(...)
circundante é opcional.
Portanto, temos um array contendo algumas strings e um monte de hashtables com as chaves Name
e Expression
, e esse array é um argumento sendo passado para Select-Object
. Ou seja, é o argumento -Property
. Observe esta linha do doc do SS64:
To add a calculated property to an object, specify a hash table as a value of the -Property
parameter. The hash table must include two keys: Name and Expression with the Expression key assigned a script block that will determine the value of the property.
Então tudo isso faz um pouco mais de sentido agora. É apenas Select-Object
transformando a entrada, e está reunindo vários atributos "calculados" (determinados pelo bloco de scripts) e um atributo "não calculado" (já presente no objeto de entrada) para o objeto de saída.
Uma pequena nota: acredito que este atributo calculado em particular é um tanto bobo:
@{Name="LastWriteTime";Expression={$_.LastWriteTime}}
Não vejo nenhum motivo para que ele não tenha sido selecionado diretamente como Name
.