Na enige drukte ben ik verder aan het schrijven aan mijn scriptje. Vervelend probleem: ik wil mijn screenoutput rechtstreeks naar een tekstbestand (of CSV) schrijven maar het lukt me niet. Ik heb alles al proberen pipen maar het geeft errors. Ik heb de FOREACH proberen wrappen maar dan krijg ik een leeg outputfile. De volgende functie die ik ga implementeren moet zoeken in dat automatisch gecreeerde bestand, dus ik zit wat vast 
Concreter uitleggen wat de bedoeling is: het gaat om de functie NewDb. Er moet een bestand aangemaakt wordt met per lijn een vermelding van de PC en de geinstalleerde software. Een andere functie gaat die info filteren zodat je meteen kunt zien bijvoorbeeld welke PCs nog niet naar Office 2007 geupgrade zijn. Ik had zo'n tool gemaakt als batch met pstools, maar een extern programma aanroepen in powershell met een relatief pad is niet vanzelfsprekend en bovendien onnodig aangezien powershell het zelf moet kunnen. Volledigheidshalve toch even mijn batchbestandje:
Werkt perfect, maar nu wil ik hetzelfde dus in PS voor elkaar krijgen. De gewenste output krijg ik dus wel op het scherm, maar niet in een bestandje.
Kritiek inzake good practice is daarnaast ook welkom; ik ben maar een wannabe-programmeur. Zoals je hopelijk merkt hieronder doe ik wel mijn best om mijn code leesbaar te houden.
Ik heb wel de indruk dat er behalve elevator niet veel mensen hier PS gebruiken :-/
Edit: Grrr, ben ik alweer mijn titel vergeten
Kan iemand er "[PowerShell] Screenoutput naar file" van maken AUB?
PS. En als er iemand weet of, en zo ja, waar het serienummer van een printer verstopt zit in de Win32 classes, feel free to let me know
Ik vrees er alleen wat voor, want ik heb de MSDN al goed uitgepluisd
Concreter uitleggen wat de bedoeling is: het gaat om de functie NewDb. Er moet een bestand aangemaakt wordt met per lijn een vermelding van de PC en de geinstalleerde software. Een andere functie gaat die info filteren zodat je meteen kunt zien bijvoorbeeld welke PCs nog niet naar Office 2007 geupgrade zijn. Ik had zo'n tool gemaakt als batch met pstools, maar een extern programma aanroepen in powershell met een relatief pad is niet vanzelfsprekend en bovendien onnodig aangezien powershell het zelf moet kunnen. Volledigheidshalve toch even mijn batchbestandje:
Batchfile:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
| @ECHO OFF GOTO Menu :Menu CLS ECHO. ******************************** ECHO. ** MIJN WERKGEVER ;-) ** ECHO. ** Network Version Check Tool ** ECHO. ** ** ECHO. ******************************** ECHO. ECHO. ECHO. ECHO. CHOOSE ECHO. 1. Search in existing version database (fast) ECHO. 2. Search in new version database (slow) ECHO. 3. Edit search strings ECHO. 4. Edit network ECHO. ECHO. q. Quit GOTO GetChoice :GetChoice SET /p _choice= IF "%_choice%"=="1" goto GetOutput IF "%_choice%"=="2" goto GetResults IF "%_choice%"=="3" goto GetStrings IF "%_choice%"=="4" goto GetNetwork IF "%_choice%"=="q" EXIT ECHO Invalid choice, please try again or press q to quit. GOTO GetChoice :GetStrings NOTEPAD.EXE STRINGS.TXT GOTO Menu :GetNetwork NOTEPAD.EXE NETWORK.TXT GOTO Menu :GetResults psinfo.exe @NETWORK.TXT -s -u -p >RESULTS GOTO GetOutput :GetOutput findstr /S /I /G:STRINGS.TXT RESULTS >OUTPUT.TXT SET _choice= NOTEPAD.EXE OUTPUT.TXT CLS GOTO Menu |
Werkt perfect, maar nu wil ik hetzelfde dus in PS voor elkaar krijgen. De gewenste output krijg ik dus wel op het scherm, maar niet in een bestandje.
Kritiek inzake good practice is daarnaast ook welkom; ik ben maar een wannabe-programmeur. Zoals je hopelijk merkt hieronder doe ik wel mijn best om mijn code leesbaar te houden.
Ik heb wel de indruk dat er behalve elevator niet veel mensen hier PS gebruiken :-/
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
| #TO DO: #- Populating should overwrite NETWORK, not append #- Add/Edit NETWORK through interface, not Notepad. Idem for the search query. #- Finish OldDB and NewDB function #- Create AddSoft and RemSoft function ############################################################################ # VARIABLES # ############################################################################ # Error handling. $ErrorActionPreference = “SilentlyContinue” # IP range. Syntax: w.x.y.(z->upperlimit). w, x and y are only for BRU of course. $w = 10 $x = 224 $y = 253 $z = 0 $upperlimit = 254 # Variable writing content to the NETWORK file $network = "NETWORK" # Array gets filled with the content from NETWORK $arrComputers = get-Content -Path "NETWORK" # Gets the password from the KEY file $password = get-content KEY | convertto-securestring # Useless but for completeness' sake $username = $username # Getting rid of the fancy windows prompt and allow terminal input of credentials $credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $username,$password ############################################################################ # FUNCTIONS # ############################################################################ # ErrorAction points to the trap. FUNCTION trap { Continue } # Making a 'pause'-command because PowerShell does not have it... FUNCTION Pause ($Message=" Press any key to continue...") { Write-Host -NoNewLine $Message $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") Write-Host "" } # The retro-introscreen :-) FUNCTION Start { CLS Write-Host " #####################################################" Write-Host " # #" Write-Host " # BLABLABLABLA :-) REMOTE ADMINISTRATION SCRIPT #" Write-Host " # #" Write-Host " #####################################################" Write-Host "" Write-Host "" Write-Host "" Write-Host "" } # Very important function to allow the script to log on a remote computer FUNCTION Credit { Start $username = read-host " Please enter your username" read-host -assecurestring " Please enter your password"| convertfrom-securestring | out-file KEY write-host "" Pause Start MainMenu } # Simple command to open a textfile with row-by-row the different IPs. FUNCTION EditNet { Start Write-Host " Opening Notepad..." NOTEPAD.EXE NETWORK Start MainMenu } # Check online hosts and write their addresses to a file called "NETWORK". FUNCTION PopNet { Start Write-Host " Checking hosts on the network..." Write-Host "" WHILE ($Z -lt $upperlimit) { $address = "$w.$x.$y.$z" $z++ $address PING -n 1 -w 50 $address > $null IF ($Lastexitcode -eq 0) {$address >> $network} } Pause Start MainMenu } # Fetch the ObjectItems from the different classes on the hosts. FUNCTION GetInfo { Start Write-Host " Fetching information from hosts..." Write-Host "" FOREACH ($strComputer in $arrComputers) { $colItems = Get-WmiObject -class "Win32_ComputerSystem" -namespace "root\CIMV2" -computername $strComputer -ErrorAction Stop FOREACH ($objItem in $colItems) { write-host Write-host " Computer Name: " $objItem.Name add-content output.txt "Computer Name: $objItem.Name" Write-host " Domain : " $objItem.Domain add-content output.txt "Domain : $objItem.Domain" } $colItems = Get-WmiObject -class "Win32_NetworkAdapterConfiguration" -filter IPEnabled=TRUE -namespace "root\CIMV2" -computername $strComputer -EA Stop FOREACH ($objItem in $colItems) { Write-host " IP address : " $objItem.IPAddress Write-host " MAC address : " $objItem.MACAddress } $colItems = Get-WmiObject -class "Win32_BIOS" -namespace "root\CIMV2" -computername $strComputer -EA Stop FOREACH ($objItem in $colItems) { Write-host " Manufacturer : " $objItem.Manufacturer write-host " BIOS Version : " $objItem.SMBIOSBIOSVersion write-host " Serial Number: " $objItem.SerialNumber } $colItems = Get-WmiObject -class "Win32_ComputerSystem" -namespace "root\CIMV2" -computername $strComputer -EA Stop FOREACH ($objItem in $colItems) { write-host " Model Name : " $objItem.Model $CalcMem = [math]::round($objItem.TotalPhysicalMemory/(1024*1024*1024),2) write-host " Total RAM : " $CalcMem GB write-host } } Pause Start MainMenu } # Allows the user to enter the search strings FUNCTION SearchQuery { Start Write-Host " Opening Notepad..." NOTEPAD.EXE QUERY ViewSoft } # Searches in the existing RESULTS-file FUNCTION OldDB { Start Pause ViewSoft } # Creates a new RESULTS-file and searches in it FUNCTION NewDB { Start Write-Host " Fetching information from hosts..." Write-Host "" FOREACH ($strComputer in $arrComputers) { $colItems = get-wmiobject -class "Win32_Product" -namespace "root\CIMV2" -computername $strComputer foreach ($objItem in $colItems) { write-host " "$strComputer ": " $objItem.Caption $objItem.Version } write-host "" } Pause OldDB } # The menu for viewing installed software FUNCTION ViewSoft { Start Write-Host " Current database:" Write-Host "" Write-Host " a. Enter search query" Write-Host " b. Search current database (fast)" Write-Host " c. Search new database (slow)" Write-Host "" Write-Host " q. Return to Main Menu" Write-Host "" Write-Host "" $choice2 = Read-Host " Please choose" Write-Host "" SWITCH ($choice2) { a {SearchQuery} b {OldDB} c {NewDB} q {MainMenu} default {" You did not make a valid choice!";Pause;Start;ViewSoft} } } # Function to remove software from the computers in the NETWORK-file. FUNCTION RemSoft { Write-Host " Not implemented yet." MainMenu } # Function to add software to the computers in the NETWORK-file. FUNCTION AddSoft { Write-Host " Not implemented yet." MainMenu } # Fetch the ObjectItems from the different classes on the hosts - Printer version. FUNCTION PrintInfo { Start Write-Host " Fetching information from hosts..." Write-Host "" FOREACH ($strComputer in $arrComputers) { $colItems = get-wmiobject -class "Win32_Printer" -namespace "root\CIMV2" -computername $strComputer FOREACH ($objItem in $colItems) { write-host " Computer Name: " $objItem.SystemName write-host " Printer Name : " $objItem.Name write-host " Driver Name : " $objItem.DriverName write-host } } PAUSE Start MainMenu } # The main menu of this script FUNCTION MainMenu { Start Write-Host " 0. Logon as Administrator" Write-Host "" Write-Host " 1. Edit IP array" Write-Host " 2. Populate IP array" Write-Host " 3. Get hardware information" Write-Host " 4. Get printer information" Write-Host " 5. View installed software" Write-Host " 6. Remove software" Write-Host " 7. Add software" Write-Host "" Write-Host " q. Quit" Write-Host "" Write-Host "" $choice1 = Read-Host " Please choose" Write-Host "" SWITCH ($choice1) { 0 {Credit} 1 {EditNet} 2 {PopNet} 3 {GetInfo} 4 {PrintInfo} 5 {ViewSoft} 6 {RemSoft} 7 {AddSoft} q {EXIT} default {" You did not make a valid choice!";Pause;Start;MainMenu} } } ############################################################################ # MAIN ROUTINE # ############################################################################ # So the program knows where to start :-) MainMenu |
Edit: Grrr, ben ik alweer mijn titel vergeten
PS. En als er iemand weet of, en zo ja, waar het serienummer van een printer verstopt zit in de Win32 classes, feel free to let me know

[ Voor 219% gewijzigd door YellowOnline op 09-03-2009 16:35 ]